views:

159

answers:

1

Hello

My business directory application calls for 3 chained select boxes, and I'm using cakephp to build this application.

The hierarchy and order of choices for the sections is this:

1 - business group

2 - business type

3 - city (included in table customer)

The relationships are:

  • customer HABTM business types

  • business groups have many business types

  • business types have one business group, HABTM customers

I have searched for jquery plugins that help with this, and found one by Remy Sharp, but it doesn't have the more complex relationships I have. http://remysharp.com/2007/09/18/auto-populate-multiple-select-boxes/

What I imagine happening is the first selection box (business groups) is pre-populated and once a selection is made, an event listener send a message that filters the second selection box, and the same for the third.

What I don't know is how to structure the search action based on the event listener.

Any advice or am I way off base?

As always, I come to the well for help.

Much appreciated. Paul


Thanks very much Nick, I've read many of your posts I really appreciate your response.

I've followed your instructions but have run into problems. I've tried my best to resolve them but haven't figured it out.

This is what I've done so far:

1) created 'chained' actions in both the business_type and business_directory (renamed customer to business directory, which is more appropriate.)

business type chained action:

function chained($business_group_id) {
    $business_types = $this->BusinessType->find('list', array(
        'conditions' => array( 'BusinessType.business_group_id' => $business_group_id)
        ));

         $this->set('business_types', $business_types);
     }

business directory chained action:

function chained($business_type_id) {
    $business_directories = $this->BusinessDirectory->bindModel(array( 'hasOne' => array('business_directories_business_types' )));         
    $business_directories = $this->BusinessDirectory->find('all', array(
        'fields' => array( ' BusinessDirectory.city'),
        'conditions' => array( 'business_directories_business_types.business_type_id' => $business_type_id)
        ));
            $this->set('business_directories', $business_directories);
     }

I did find that with a HABTM relationship, using find 'list' didn't create the join querry, whereas find 'all' did.

2) I then created a search action in the business directory and corresponding view.

For the business groups I created a getList action to populate the option list in the search form:

function getList() {
     return $this->BusinessGroup->find('list');
}

In the search view, I've added the javascript for the chain select:

<script type="text/javascript">
<!--
$(function () {
    var group = $('#businessGoup');
    var type = $('#businessType');
    var city = $('#businessDirectoryCity');

    type.selectChain({
        target: city,
        url:  '../business_directories/chained/'+$(this).val(),
  data: { ajax: true, anotherval: "anotherAction" }
    });

    group.selectChain({
        target: type,
        url: '../business_types/chained/'+$(this).val()   
    }).trigger('change');

});
//-->
</script>

And the form:

create('business_directories', array('action'=>'/search_results')); ?>

    <div class="selHolder">
    <?php
    echo $form->input('business_group_id',
      array( 'type' => 'select',
           'id' => 'businessGoup',
          'empty' => '-- Select Business Group --',
          'multiple' => true,
          'options' => $this->requestAction('/business_groups/getList' ),
          'label' => 'Business Group'));
     ?>
    </div>

    <div class="selHolder">
    <?php
        echo $form->input('business_type.id',
      array( 'type' => 'select',
          'id' => 'businessType',
          'empty' => '-- Select Business Type --',
          'multiple' => true,
          'options' => 'none selected',
          'label' => 'Business Type'));
     ?>
    </div>

     <div class="selHolder">
    <?php
    echo $form->input('business_directories.id',
      array( 'type' => 'select',
          'id' => 'businessDirectoryCity',
          'empty' => '-- Select City --',
          'multiple' => true,
          'options' => 'options',
          'label' => 'City'));
    ?>
    </div>

</fieldset>
<?php echo $form->end('Search'); ?>

When I test the business type chain function, /business_types/chained/1, everything works.

But when I test the search view, I get a javascript alert error. Then when I check firebug, I get the following two errors:

Warning (2): Missing argument 1 for BusinessTypesController::chained() [APP\controllers\business_types_controller.php, line 71]

Notice (8): Undefined variable: business_group_id [APP\controllers\business_types_controller.php, line 73]

Any additional help with this is very much appreciated.

Thanks, Paul

+1  A: 

What you need is to have 2 actions in the controllers (business_type and customer).

each action should look like this. In that case for the business type

function chained($parent_id){
    $business_types = $this->BusinessType->find('list', array('conditions'=>'BusinessType.business_group_id'=>$parent_id));
    $this->set('business_types', $business_types);
}

of course you need also view for that action which will format the values in the proper format for the chained select.

For Business group you need to show all values directly so no ajax is needed.

The Customer controller's action is similar, but you need to select cities of all related customers.

Then with the chained select you need to set the proper elements and set the proper actions which need to be called.

i.e.:

$('#id-of-the-business-group').selectChain({
    target: $('#id-of-the-business-type-field'),
    url: '/business_types/chained/'+$(this).val()
});
Nik
Thanks Nick. I've added some edits to my question to explain the problems I've run into. Any help is much appreciated.
Paul