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…

Advertisements

11 thoughts on “Yii Dependent Dropdown in a CActiveForm

  1. Hi, thanks..

    This is not working for me in CActiveform. It worked for me in CHtml::dropDownList as given in wiki/24. Any guess??

    Reply
  2. Hi,
    First, thanks for sharing.
    But i’ve been stuck with this for a while now.
    I have to choose a in the 1st drop down, then a in a 2nd drop down list.
    Because there are hundreds of workers, it would be nice to reduce/filter according to the choice.

    This is all in a form and a controller of a 3rd model which is linked to .

    The form:

    labelEx($model,’office’); ?>
    dropDownList($model,’office’,
    CHtml::listData(Office::model()->findAll(),’id_office’,’officename’),
    array(//’onChange’=>’javascript:description()’,’prompt’=>’–Choose Office–‘,
    ‘ajax’=>array(‘type’=>’POST’,’url’=>CController::createUrl(‘agents’),
    ‘update’=>’#Event_agent_id]’,
    )));
    ?>
    error($model,’office’); ?>

    labelEx($model,’agent_id’); ?>
    dropDownList($model,’agent_id’,CHtml::listData(
    Agent::model()->findAll(),’id_agent’,’infos’
    )); ?>
    error($model,’agent_id’); ?>

    Then:
    public function actionAgents() {
    $agents = Agent::model()->findAll(‘office_id=:office_id’,
    array(‘:office_id’=>(int)$_POST[‘Event‘]));
    $return = CHtml::listdata($agents,’id_agent’,’infos’);
    foreach ($return as $agentId=>$agentInfo)
    echo CHtml::tag(‘option’,array(‘value’=>$agentId),CHtml::encode($agentInfo),true);
    }

    So… what am I doing wrong ? 🙂
    Thx in advance.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s