[Solved]problem with dependent dropdownlist

Hi,

I have refered the wiki and am using the same logic for my problem. My code is

_form code:




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'footprint-state-form',

	'enableAjaxValidation'=>false,

	)); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<?php echo $form->errorSummary($model); ?>

	

	<div class="row">

    <?php echo $form->labelEx($model,'state_name'); ?>

    <?php 

          $state_var = new CDbCriteria; 

          $state_var->order = 'state_name ASC';

    ?>

	<?php echo $form->dropDownList($model,'Footprint_State_id',CHtml::listData(FootprintState::model()->findAll(array('group'=>'state_name')),'Footprint_State_id','state_name'), 

				array('ajax'=>array(

							'type'=>'POST',

							'url'=>CController::createUrl('FootprintStateController/dynamiccounty'),

							'update'=>'#county_id'

							)       

						));

			  

			  //empty since it will be filled by the other dropdown

			echo CHtml::dropDownList('county_id','', array());

	?>

	<?php //echo $form->error($model,'Footprint_State_id'); ?>

	</div>	

controller code:




public function actionDynamiccounty()

	{

		$data=footprintCounty::model()->findAll('parent_id=:parent_id', 

                  array(':parent_id'=>(int) $_POST['Footprint_State_id']));

		$data=CHtml::listData($data,'Footprint_County_id','county');

		foreach($data as $id=>$value)

		{

			echo CHtml::tag('option',

                   array('value'=>$id),CHtml::encode($value),true);

		}

	}



I get the first dropdownlist populated but on selection nothing is populated in the second dropdownlist. I get an empty dropdown. I browsed through many forum post but found no solution. I feel that the function dynamiccounty in the controller is not called by the first dropdownlist. Why? Not able to resolve. Please help me.

Thanks

change

CController::createUrl(‘FootprintStateController/dynamiccounty’)

to

CController::createUrl(‘FootprintState/dynamiccounty’)

Thanks qijunz, I tried your solution but no change.

Add a dummy div <div id=“testController”></div> and try updating that one. In your controller, comment out everything and just echo ‘Test’. That should tell you if your controller is being called. Also, please verify you have added ActionDynamicCountry to your Controller AccessRules.

View:




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

        'id'=>'footprint-state-form',

        'enableAjaxValidation'=>false,

        )); ?>


        <p class="note">Fields with <span class="required">*</span> are required.</p>


        <?php echo $form->errorSummary($model); ?>

        

        <div class="row">

    <?php echo $form->labelEx($model,'state_name'); ?>

    <?php 

          $state_var = new CDbCriteria; 

          $state_var->order = 'state_name ASC';

    ?>

        <?php echo $form->dropDownList($model,'Footprint_State_id',CHtml::listData(FootprintState::model()->findAll(array('group'=>'state_name')),'Footprint_State_id','state_name'), 

                                array('ajax'=>array(

                                                        'type'=>'POST',

                                                        'url'=>CController::createUrl('FootprintStateController/dynamiccounty'),

                                                        'update'=>'#testController'

                                                        )       

                                                ));

                          

                          //empty since it will be filled by the other dropdown

                        echo CHtml::dropDownList('county_id','', array());

        ?>

        <?php //echo $form->error($model,'Footprint_State_id'); ?>

        </div> 


<div id="testController"></div> 



Controller:




public function actionDynamiccounty()

        {

                /*$data=footprintCounty::model()->findAll('parent_id=:parent_id', 

                  array(':parent_id'=>(int) $_POST['Footprint_State_id']));

                $data=CHtml::listData($data,'Footprint_County_id','county');

                foreach($data as $id=>$value)

                {

                        echo CHtml::tag('option',

                   array('value'=>$id),CHtml::encode($value),true);

                }*/

echo 'Test';

        }



Matt

Thanks Matt.

When i update=#testController, it displays the ‘Test’ from Controller but as soon as i change update to #county_id it does not go to the controller. What does it mean?

Two other things I would check are:

[list=1]

[*]The POST param is being passed and has a value

[*]The FindAll() function is returning a dataset

[/list]

Try to echo the value of the POST param

Try to echo a number of elements from the findAll function.

Again, use the testController div for results.

Matt

Sorry for not noticing this before. You’re not passing any POST values in your AJAX request. Notice the “data” param. I usually do it this way:




         <div class="row">

            <?php echo $form->labelEx($model, 'category_id'); ?>

            <?php

            echo $form->dropDownList($model, 'category_id',

                CHtml::listData($categories, 'id', 'name'),

                array(

                    'prompt' => 'View All',

                    'ajax' => array(

                        'type' => 'POST',

                        'url' => CController::createUrl('/project/dynamicSubCategory'),

                        'update' => '#' . CHtml::activeId($model, 'sub_category_id'),

                        'data' => array('showPrompt' => '1', 'categoryId' => 'js:this.value'),

                        'beforeSend' => "function(jqXHR, settings)

                        {

                            $('#categoryLoading').addClass('loading');

                        }",

                        'complete' => "function(jqXHR, textStatus)

                        {

                            $('#categoryLoading').removeClass('loading');

                        }",

                    ),

                    'class' => 'dynamicDropDown',

            ));

            ?>

            <?php echo $form->error($model, 'category_id'); ?>

        </div>



Matt

Problem resolved. I refered to this post and could sort out my problem. Thanks Mdomba.

Thanks Matt for all your help.

Here’s solution with example…

There are two tables Employee and department

I want to show all employees in selected department…

i.e department is selected in first drop down and second dropdown should show employees in that department…

Here’s code…


	<div class="row">

		<?php

			$list=CHtml::listData(Department::model()->findAll(),'department_id','department_name');

			echo CHtml::dropDownList('department_id','', $list,

			array(

			'empty'=>'Please Select',

			'ajax' => array(

			'type'=>'POST', //request type

			'url'=>CController::createUrl('Employee/dynamicemployee'), //url to call.

			'update'=>'#emp_id', //selector to update

			))); 

		?>

	</div>

	<div id="row">

		<?php

			//empty since it will be filled by the other dropdown

			echo CHtml::dropDownList('emp_id','', array(),array('empty'=>'Select','style'=>'width:120px;'));		

		?>

	</div>



Here is my controller code…


	public function actionDynamicemployee()

	{

		$data=Employee::model()->findAllBySql('select emp_id, first_name from employee where department_id='.$_POST['department_id']);

	 	$data=CHtml::listData($data,'emp_id','first_name');

		foreach($data as $value=>$name)

		{

			echo CHtml::tag('option',

			array('value'=>$value),CHtml::encode($name),true);

		}

	}



Don’t forget to change access rules…

THis example is working fine but if I use activeDropDown then it’s not working. Can you tell me how to use activeDropDown?

Any help how to use activeDropdown on dependent droptdown?

At work at the moment. Will take a look when I get home.

Matt

@nemo,

Can you post your full view code. Are you using an ActiveFormWidget?

I.e.




$form = $this->beginWidget('CActiveForm', array(



activeDropDownList should work.

Matt

Here is the Form





<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'test-execution-form',

	'enableAjaxValidation'=>true,

)); ?>


	

<?php echo $form->errorSummary($model); ?>

<?php echo CHtml::beginForm(); ?>


<br><br> 

<table class="dataGrid">

<tr>

		<td><?php echo $form->labelEx($model,'Region_id');?></td>

		<td>

	        <?php 

	        

            $list=CHtml::listData(Region::model()->findAll(),'id','region'); 

            echo CHtml::dropDownList('Region_id','', $list, 

            array( 

           'empty'=>'Please Select Region', 

           'ajax' => array( 

           'type'=>'POST', //request type 

           'url'=>CController::createUrl('test/dynamicRegion'), //url to call. 

           'update'=>'#Lab_id', //selector to update 

           'data'=>'js:$(this).serialize()', 

            

           )));

           

           ?>

          

        </td>

     </tr>

     <tr>

     	<td><?php echo $form->labelEx($model,'Lab_id');?></td>

     	<td> 

            <?php 

            	//echo CHtml::activeDropDownList($model,'Lab_id',array());

                        //empty since it will be filled by the other dropdown 

              echo CHtml::activeDropDownList($model,'Lab_id', array(),array('id'=>'Lab_id'));

               echo CHtml::activeHiddenField($model,'Region_id');                  

            ?>

        </td>

     </tr>


<tr>

		<td>&nbsp;</td>

		<td ><?php echo CHtml::submitButton('Search'); ?></td>

	</tr>

</table>

<?php echo CHtml::endForm(); ?>

<?php $this->endWidget(); ?>


</div><!-- form -->



Here is my Controller




public function actionDynamicRegion(){

                $data=Lab::model()->findAllBySql('select * from Lab where id>=1 AND Region_id='.$_POST['Region_id']); 

                $data=CHtml::listData($data,'id','name'); 

                foreach($data as $value=>$name) 

                { 

                        echo CHtml::tag('option', 

                        array('value'=>$value),CHtml::encode($name),true); 

                } 

		


    } 



I want to use activeDropDownList on Region_id. I got the Lab_id.

Have any IDEA waterloomatt?

@nemo,

Please get rid of




<?php echo CHtml::beginForm(); ?>



and




<?php echo CHtml::endForm(); ?>



At the moment, you’re creating two forms. Let me know if that helps.

Matt

Hello Matt,

I did but still not reading, I think problem is here




 <?php 

	        

            $list=CHtml::listData(Region::model()->findAll(),'id','region'); 

            echo CHtml::dropDownList('Region_id','', $list, 

            array( 

           'empty'=>'Please Select Region', 

           'ajax' => array( 

           'type'=>'POST', //request type 

           'url'=>CController::createUrl('test/dynamicRegion'), //url to call. 

           'update'=>'#Lab_id', //selector to update 

           'data'=>'js:$(this).serialize()', 

            

           )));

           

           ?>



I’m using CHtml::dropDownList, but we need CHtml::activeDropDownList.

Try this:




<div class="row">

        <?php echo $form->labelEx($model, 'category_id'); ?>

        <?php

        $categories = CHtml::listData(Category::model()->findAll(), 'id', 'name');

        asort($categories);

        echo CHtml::activeDropDownList($model, 'category_id', $categories, array(

            'prompt' => 'View All',

            'ajax' => array(

                'type' => 'POST',

                'url' => CController::createUrl('/project/dynamicSubCategory'),

                'update' => '#' . CHtml::activeId($model, 'sub_category_id'),

                'data' => array('showPrompt' => '1', 'categoryId' => 'js:this.value'),

                'beforeSend' => "function(jqXHR, settings)

                        {

                            $('#categoryLoading').addClass('grid-view-loading');

                            $('#" . CHtml::activeId($model, 'sub_category_id') . "').attr('disabled', 'disabled');

                        }",

                'complete' => "function(jqXHR, textStatus)

                        {

                            $('#categoryLoading').removeClass('grid-view-loading');

                            $('#" . CHtml::activeId($model, 'sub_category_id') . "').removeAttr('disabled');

                        }",

            ),

            'class' => 'dynamicDropDown',

        ));

        ?>

    </div>



Ignore the asort - my DB is encrypted so I can’t use RDBMS sorting. Notice I pass the model and the field id to it.

Matt

I tried ur code. when I change Region then Lab data does not change. It’s blank

Here is my update code




<?php

        $categories = CHtml::listData(Region::model()->findAll(), 'id', 'region');

        asort($categories);

        echo CHtml::activeDropDownList($model, 'Region_id', $categories, array(

            'prompt' => 'View All',

            'ajax' => array(

                'type' => 'POST',

                'url'=>CController::createUrl('test/dynamicRegion'), //url to call.

                'update' => '#' . CHtml::activeId($model, 'Lab_id'),

                'data' => array('showPrompt' => '1', 'id' => 'js:this.value'),

                'beforeSend' => "function(jqXHR, settings)

                        {

                            $('#categoryLoading').addClass('grid-view-loading');

                            $('#" . CHtml::activeId($model, 'Lab_id') . "').attr('disabled', 'disabled');

                        }",

                'complete' => "function(jqXHR, textStatus)

                        {

                            $('#categoryLoading').removeClass('grid-view-loading');

                            $('#" . CHtml::activeId($model, 'Lab_id') . "').removeAttr('disabled');

                        }",

            ),

            'class' => 'dynamicDropDown',

        ));

        ?>

          

        </td>

     </tr>

     <tr>

     	<td><?php echo $form->labelEx($model,'Lab_id');?></td>

     	<td> 

            <?php 

            	//echo CHtml::activeDropDownList($model,'Lab_id',array());

                        //empty since it will be filled by the other dropdown 

              echo CHtml::activeDropDownList($model,'Lab_id', array(),array('id'=>'Lab_id'));

            ?>

        </td>

     </tr>




Can you tell me where I did mistake

Hi nemo,

Sorry, I meant your should just use my 1 line to use the model and property name.


echo CHtml::activeDropDownList($model, 'Region_id', $categories, array(

Don’t change the rest of your code.

Matt