Yii Dependent Dropdown in a CActiveForm

When I started using Yii Framework, I met some challenges (common challenges to most of the newbies). It took me sometime to go through different forums and wiki documents and this at some point extended development time in some of my projects. In this article, am going to share a way forward on how to create dependent dropdown in Yii Framework. You can get more details at http://www.yiiframework.com/wiki/24/. Straight and clean, this worked for me so I guess it has to work for you too.

1. The database (MySQL):

I have a REGION table with the following fields:

1. id INT NOT NULL PRIMARY KEY AUTOINCREMENT
2. region_name VARCHAR(30)

Then a DISTRICT table with the following attributes

1. id INT NOT NULL PRIMARY KEY AUTOINCREMENT
2. region_id INT NOT NULL
3. district_name VARCHAR(30)

Also a CUSTOMER table with the following fields:

1. id INT NOT NULL  PRIMARY KEY AUTOINCREMENT
2. customer_name VARCHAR(100)
3. district_id INT NOT NULL
4. region_id INT NOT NULL
2. The views:

In the views directory, I have a customer directory in which I have a form (_form).
This is how it looks:

<td><?php echo $form->labelEx($model, ‘region_id’); ?></td>
<td>
<?php
$regions = CHtml::listData(Region::model()->findAll(array(‘order’ => ‘id’)), ‘id’, ‘region_name’);
echo $form->dropDownList($model, ‘region_id’, $regions, array(
‘prompt’ => ‘–select region–‘,
‘ajax’ => array(
‘type’ => ‘POST’,
‘url’ => CController::createUrl(‘customer/districts’),
‘update’ => ‘#Customer_district_id’,
)
));
?>
</td>
<td><?php echo $form->error($model, ‘district_id’); ?></td>
<td><?php echo $form->labelEx($model, ‘district_id’); ?></td>
<td><?php echo $form->dropDownList($model, ‘district_id’, array(), array(‘style’ => ‘width:300px;’)); ?></td>
<td><?php echo $form->error($model, ‘district_id’); ?></td>

Notice that the customer controller is the current controller where this form goes when submitted and an action

districts which we are going to see soon. You can also see that in the district dropdown we passed an empty array
of districts because it is going to be filled with an ajax update after we have selected a region in the dropdown.

3. The controller (CustomerController)

In the customer controller, you need to add an action districts to the accessRules() so that it can be accessible. Now lets see how the districts action look like.


public function actionDistricts() {

$districts = District::model()->findAll(‘id=:id’, array(‘:id’ => (int) $_POST[‘Customer’][‘region_id’]));
$return = CHtml::listData($districts, ‘id’, ‘district_name’);
foreach ($return as $districtId => $districtName) {
echo CHtml::tag(‘option’, array(‘value’ => $districtId), CHtml::encode($districtName), true);
}
}

…and, guess what…. BINGO!!!

Thats all you need.

Nice coding to y’all…