Please help with dependent drop down!

Hi, everyone. I followed the tutorial on dependent drop downs and just can’t seem to get the dependent selector populated with the values after selecting the value in the first selector.

What I am trying to accomplish is to select an adtype_id and then use that value to select all the ad rates that have that adtype_id from the AdRates model:

TransactionsController File




public function actionGetadrates()

{


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

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


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

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

            {

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

            }


 

}	 



View File:




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

	'id'=>'transactions-form',

	'enableAjaxValidation'=>false,

)); ?>


<div class="row">

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

		<?php echo $form->dropDownList($model,'adtype_id', CHtml::listData(AdTypes::model()->findAll(), 'id', 'description'), array('empty'=>'--please select--'),

		

array(

'ajax' => array(

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

'url'=>CController::createUrl('Transactions/Getadrates'), //url to call.

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

))); 


 ?>

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

	</div>

		

	<div class="row">

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

		<?php echo $form->dropDownList($model,'adrate_id',array()); ?>

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

	</div>



How can I troubleshoot this since it is an ajax call? Is there any way of testing to see if the action is even being executed or if the data is even being produced?

Hello, Firefox’s Firebug is your friend (look in the Net tab, then the XHR tab when it’s an ajax call)

Anyway, I believe your dropDownList syntax and your update selector are both incorrect. I suppose your model name is Transactions




...

<?php echo $form->dropDownList(

    $model,'adtype_id',

    CHtml::listData(AdTypes::model()->findAll(), 'id', 'description'),

    array(

          'empty'=>'--please select--'),

          'ajax' => array(

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

              'url'=>CController::createUrl('Transactions/Getadrates'), //url to call.

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

              // or 'update' => '#' + CHtml::activeId($model, 'adrate_id')

          )

    )

); ?>

...



Also you have to make sure that you’ve added your Getadrates action has the correct accessRules() in your Transactions controller.

This is very frustrating. I have tried a lot of different approaches and I can’t see where my syntax is incorrect. In any case, here is the latest iteration.

Controller File







public function getPeriods($criteria)

//this function populates the first dropdown


   {

         if($criteria == 0)

		 //this means get all periods

		 {

	     $periods = Periods::model()->findAll(		 

                 array('order' => 'description'));

		 

		 }

		 else

		 //only get periods that have events

		 {

		 

		 $sql = "SELECT DISTINCT tbl_periods.id, tbl_periods.description FROM tbl_periods

		         INNER JOIN tbl_events ON tbl_events.period_id = tbl_periods.id

				 INNER JOIN tbl_donations ON tbl_donations.event_id = tbl_events.id

				 ";

		 

		

	 

	     $periods = Periods::model()->findAllBySql($sql,		 

                 array('order' => 'description'));

		 

	 

		 }

		 

      

         $periodlist = CHtml::listData($periods, 

                'id', 'description');    

				

				

	  return $periodlist;			


      }   


        public function actiongetEvents()

        //this function is called through ajax to populate the dependent dropdown

    {

     	

	$events = Events::model()->findAll('period_id=:selected_id', 

                 array(':selected_id'=>(int) $_POST['period_id']));

	

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

	

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

   {

        

         echo CHtml::tag('option',

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

    }





public function actionIndex()


	{

	         

		$model = new ReportForm;	 

 

			 

		if(isset($_POST['ReportForm']))

		{

		//some code goes here

				

		}


	   $this->render('index',array('model'=>$model));

	} 



Here is the entire form using the CActiveForm widget




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

	'id'=>'reports-form',

	'enableAjaxValidation'=>true,

	

	)); ?>


	<div class="row">

	        <?php echo $form->dropdownList($model,'period_id',$this->getPeriods(1),array('prompt'=>'---Select---'),

   array('ajax'=>array(

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

'url'=>CController::createUrl('reports/getEvents'), //url to call.

'update'=>CHtml::activeId($model, 'event_id'), 

))); 




  ?>

</div>


<div class="row">

			<?php echo $form->dropdownList($model,'event_id',array() );  ?>

		</div>


		

	<div class="row buttons">

		<?php echo CHtml::submitButton('Create Graph'); ?>

	</div>


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



Notice that I even used activeId to identify the target dropdown ID as suggested in the dropdown tutorial because I saw that the rendered page showed the ID as ReportForm[event_id] instead of event_id. However, still nothing is happening. Can anyone spot where I am going wrong?

Use firebug and inspect … see what happening in the console when u select from dropdown … u can see some post error here…

use model here

$_POST[‘ur model name’][‘period_id’]





public function actiongetEvents()

        //this function is called through ajax to populate the dependent dropdown

    {

        

        $events = Events::model()->findAll('period_id=:selected_id', 

                 array(':selected_id'=>(int) $_POST['[b]ur model name[/b]']['period_id']));

        

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

        

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

   {

        

         echo CHtml::tag('option',

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

    }






the value is posting as $_POST[model-name][period_id]

try this…

Thanks for the suggestion but that didn’t work either. Any other ideas?




 public function actiongetEvents()

    {

    

    	

	$events = Events::model()->findAll('period_id=:selected_id', 

                 array(':selected_id'=>(int) $_POST['ReportForm']['period_id']));

	

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

	

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

   {

   

    

    

	echo CHtml::tag('option',

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

	

	

		  

   }

		

   

   }//end function




whats happening with firebug console ?

I used Firefox firebug to try and troubleshoot my problem but I cannot see any errors. If anyone wants to see the problem page in action, here it is:

Link to page

Have a look at this:

http://www.yiiframework.com/forum/index.php/topic/11531-solved-how-to-create-dependent-dropdown-lists/page__p__57349__hl__populating+dropdown+li+t+dynamically

Thanks for the link. I have gone through that thread and discovered that I had not added the # sign in the activeId statement to reference the event_id dropdown. I have now corrected that problem:




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



I also hard coded the selected id in the actiongetEvents function to see if that part of it was working:




 public function actiongetEvents()

    {

    

	//for testing purposes hardcoding the period_id

	$period_id = 1;

    	

 

	 $events = Events::model()->findAll('period_id=:selected_id', 

	             array(':selected_id'=> (int) $period_id));

	

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

	

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

   {   

	echo CHtml::tag('option',

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

   }

		

   

   }//end function



I then retested while checking the firebug net console and still nothing even with hardcoding the selected_id from the first dropdown. So I guess that either the function isn’t being called at all or the target dropdown isn’t being referenced correctly or perhaps both but I am still unable to figure out where exactly the problem is.

Any other suggestions would be appreciated.

Have you given the right to access this action in the access rules of your controller?

Yes, of course. I set accessRules to allow all users complete access. Then, just to be sure, I completely commented out the accessRules function as well as the filter. Still nothing.




/*

completely comment out this function

public function accessRules()

	{

		return array(

				array('allow',  

				'users'=>array('*'),

			),

		);

	}


*/



BTW, you are welcome to try the page out yourself and see if you see something that I am missing:

My link

your ajax post is not working… its sure that a js problem is there…

this is working in my app.

in view





<?php echo CHtml::dropDownList('country','',CHtml::listData(Countries::model()->findAll(array('order'=>'name ASC')),'id','name'),array('prompt'=>'Select',

	'ajax' => array(

	'type'=>'POST',

	'url'=>CController::createUrl('registration/region'),

	'update'=>'#region_id',

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

	

	))); ?>

	

	</div>

    

	<?php echo CHtml::dropDownList('region','',array(),array('prompt'=>'Select','id'=>'region_id')); ?>

    






in controller





public function actionRegion()

	{

		

		

		$data=Regions::model()->findAll('country_id=:id', 

                  array(':id'=>(int) $_POST['country']));

		}

		

				  

		echo CHtml::tag('option', array('value' => 0), CHtml::encode('Select'), true); // for select

 

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

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

		  {

			  echo CHtml::tag('option',

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

		  }

	}









Okay, I think I am getting closer to finding out what the problem is with my dependent dropdown issue. Firebug is not detecting JS on my page. When viewing the page source, I looked in the header and did not see any JS reference to Jquery or whatever Yii uses for handling ajax requests. I know this may seem like an obvious question, but isn’t there supposed to be something in the header referencing Jquery or whatever the ajax library used by Yii? Or is it handled in some other way? Do I need to register Jquery?

is there any Jquery in ur main layout?

just put this in main layout

<?php Yii::app()->clientScript->registerCoreScript(‘jquery’);?>

and in controller/action

Yii::app()->getClientScript()->registerCoreScript(‘yii’);

just try this too…I think this is a strange problem!!!.

After cup after cup of coffee and pulling out a few hairs, I finally figured out the solution to my dependent dropdown problem. :D

It was actually a syntax issue relating to the first dropdown. The prompt parameter was included in a separate comma, thus preventing the ajax call from being executed.

Here is the corrected code from the view file all working just fine:




<div class="row">

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

	    <?php echo $form->dropdownList($model,'period_id',$this->getPeriods(1),

   array(

'prompt'=>'---Select Period---',

'ajax'=>array(

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

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

//Style: CController::createUrl('currentController/methodToCall')

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

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

//leave out the data key to pass all form values through

))); 

  ?>

</div>


<div class="row">

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

			<?php echo $form->dropdownList($model,'event_id',array(),array('prompt'=>'---Waiting for selection---'));  ?>

		</div>



I want to thank everyone who assisted me!