Need help with view/controller/model and ajax

Hi:

I’m new to PHP and Yii so please bear with me, and any help is appreciated.

Tables


countries:

  • country_code char(2) (pk)

  • country_name varchar(64)

regions:

  • region_id smallint (pk)

  • region_country_code char(2) (fk->countries.country_code)

  • region_code varchar(3)

  • region_name varchar(64)

min_wage_region:

  • min_wage_id int (pk)

  • min_wage_region_id smallint (fk->regions.region_id)

  • min_wage_rate_hr decimal(8,4)

In the min_wage_region create view (_form.php) I have the following code:




<div class="row">

	<?php echo CHtml::activeLabelEx($model,'min_wage_region_id'); ?> 

	<?php

		$modelCountries = Countries::model()->findAll(array('order' => 'country_code'));

		$listCountries = CHtml::listData($modelCountries, 'country_code', 'country_name'); 

		echo CHtml::dropDownList('selected_country', '', $listCountries, array( 

			'prompt' => '(Select country)',

			'ajax' => array(

				'type'=>'POST',

				'url'=>CController::createUrl('regions/findregionsbycountry'), 	

				'update'=>'#regions_list',

				'data'=>'js:jQuery(this).serialize()',	// only send country, not whole form 

				)

			)

		);

		echo '<br />';

		echo CHtml::textArea('regions_list', ''); // will be replaced by a dropDownList when it works!

	?>

	<?php echo CHtml::error($model,'min_wage_region_id'); ?>

</div>



In RegionsController.php I have the following:




... in function accessRules()


	array('allow', // allow authenticated user to perform these actions

		'actions'=>array('create','update','findregionsbycountry'),

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

	),


... and added this function:


	/**

	 * Returns a list of regions given the country code.

	 */

	public function actionFindRegionsByCountry()

	{

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

		{

			return Regions::model()->findCountryRegions($_POST['selected_country']);

		}

	}



Finally, I added this function to the model Regions.php:




	/**

	 * Returns a list of regions given the country code.

	 */

	public function findCountryRegions($reg_ctry_code)

	{

		// search uses parameter instead of foreign key relationship

		$criteria = new CDbCriteria(array(

			'select'=>'region_id, region_name',

			'condition'=>'region_country_code=:_param',

			'order'=>'region_code ASC',

			'params'=>array(':_param'=>$reg_ctry_code),

			));

		return CHtml::listData($this->findAll($criteria), 'region_id', 'region_name');

	}



The problem is that the textArea in the view comes up empty. I have tested the model function in yiic’s command line and it works. I have also tested the view/controller/model message passing (using a constant string and also $_POST) and they work. I don’t know what’s wrong here, please help.

Thanks,

Jose

hiii,

I’m a newbie too to yii and ajax,

I’ve found a code like yours in forum and tried it, but there’s an error message that’s always coming up : Object expected … it’s driving me crazy!

I’ve simplified my code to this :

In form :

<?php echo CHtml::dropDownList(‘Services’,’’,CHtml::listData(Service::model()->findAll(), ‘id’, ‘name’), array(‘ajax’ => array(

                    'type' =&gt;'POST',


                    'url' =&gt; CController::createUrl('package/echosomething'),


                    'update' =&gt; '#Hotels',


                    )));

In package controller :

public function actionEchosomething()

    {


        echo &quot;something&quot;;


    }

But with no use!

Please help me! :-[

I’m no expert, but I think you have to provide more of your code to find out which object is missing.

I have to know why jQuery is not working in my code ? is there something I have to register or what ?

In a dropdownList, i’ve written this line :

‘onchange’=>"jQuery.ajax({‘url’:‘index.php?r=country/index’})

But it’s just not working :(

  1. Use Firebug console to monitor the ajax request being sent (and response if any).

  2. Enable logging and add trace calls to the controller action

/Tommy

After a couple of days of trying different things I got it to work (plus added a touch of style :)

However, it’s not working right when updating a record (instead of creating) - please read end of post for question, thanks!

  1. min_wage_region create view (_form.php)



<div class="row">

	<?php echo CHtml::activeLabelEx($model,'min_wage_region_id'); ?>

	<?php

		$modelCountries=Countries::model()->findAll(array('order' => 'country_code'));

		$listCountries=CHtml::listData($modelCountries, 'country_code', 'country_name');

		$listRegions=array();

		echo CHtml::dropDownList('selected_country', '', $listCountries, array(

			'prompt' => '(Select country)',

			'ajax' => array(

				'type'=>'POST',

				'url'=>CController::createUrl('regions/findregionsbycountry'),

				'update'=>'#regions_list',

				'beforeSend'=>'function(){$("#pickcountry").addClass("loading");}',

				'complete'=>'function(){$("#pickcountry").removeClass("loading");}',

				'data'=>'js:jQuery(this).serialize()',	// only send country, not whole form

				)

			)

		);

		echo '<span id="pickcountry">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>';

		echo '<br />';

		echo CHtml::activeDropDownList($model, 'min_wage_region_id', array(), array(

			'prompt'=>'(Select region)',

			'id'=>'regions_list',

		));

	?>

	<?php echo CHtml::error($model,'min_wage_region_id'); ?>

</div>



  1. RegionsController.php did not require changes from the original posted version.

  2. model Regions.php was also fixed and made to work with either $_POST or command line through yiic shell




/**

 * Returns a list of regions given the country code. 

 * Accepts command line parameter or $_POST.

 */

public function findCountryRegions($reg_ctry_code)

{

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

	{

		$reg_ctry_code=$_POST['selected_country'];

	}

	$criteria = new CDbCriteria(array(

		'select'=>'region_id, region_name',

		'condition'=>'region_country_code=:_param',

		'order'=>'region_code ASC',

		'params'=>array(':_param'=>$reg_ctry_code),

		));

	$reglist=CHtml::listData($this->findAll($criteria), 'region_id', 'region_name');

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

	{

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

		{

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

		}

	}

	else

	{

		return $reglist;

	}

}



Hope this helps someone else. Unfortunately it doesn’t work right when updating (instead of creating) a record because the dropDownLists are not populated. The idea is to display the parent (Regions) and grandparent (Countries) records in the dropDownLists, but instead they show the default "(Select Country/Region). Any ideas? Thanks again!

It is not surprising that for an existing model the lists are not populated. The active lists are only populated on change and you are creating them as empty lists. You will need to pass in the list for the regions on creation of the control (if the model is not new)

nz

Thanks for the reply. How do I do that?

Something like




$fooArray = array();

if ($model->country_code) {

  $fooArray=$this->findArrayCountryRegions($model->country_code);

}

echo CHtml::activeDropDownList($model, 'min_wage_region_id', $fooArray, array(

                        'prompt'=>'(Select region)',

                        'id'=>'regions_list',



Of course findArrayCountryRegions method needs to return an array of values as defined http://www.yiiframework.com/doc/api/CHtml#activeDropDownList-detail

nz

I tried this code but the ajax doesn’t work :(

the 2 dropdown aren’t in region or country! is their a problem with that ?:S

I would appreciate your reply :D