How to display Dependent drop-down value using ajax call with dynamically

5 followers

Hi Friends, In this tutorial I write a code display dependent drop-down value using ajax call.

Suppose We have to two table like county and state,so if display the state using county wise call a ajax on county drop-down value and fetch the state using county code.

1) First we have to create the two table and insert the some sample data

CREATE TABLE `country_master` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `country` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'Country name' COLLATE 'latin1_swedish_ci',
    `country_code` CHAR(2) NOT NULL DEFAULT '' COMMENT 'Country code' COLLATE 'latin1_swedish_ci',
    `country_code_iso3` CHAR(3) NOT NULL DEFAULT '' COMMENT 'Country code 3 character' COLLATE 'latin1_swedish_ci',
    `language` CHAR(3) NOT NULL COMMENT 'Language' COLLATE 'latin1_swedish_ci',
    `currency_name` VARCHAR(50) NULL DEFAULT NULL COMMENT 'Currency name' COLLATE 'latin1_swedish_ci',
    `currency_symbol` CHAR(3) NULL DEFAULT NULL COMMENT 'Currency symbol' COLLATE 'latin1_swedish_ci',
    `currency_rate` DECIMAL(3,3) NULL DEFAULT NULL COMMENT 'Currency rate',
    `is_publish` TINYINT(1) NOT NULL DEFAULT '1' COMMENT 'Is publish',
    PRIMARY KEY (`id`),
    INDEX `IDX_COUNTRIES_NAME` (`country`)
    )
    COLLATE='utf8_general_ci'
    ENGINE=MyISAM
    ROW_FORMAT=DYNAMIC
    AUTO_INCREMENT=1;
 
    INSERT INTO `country_master` (`id`, `country`, `country_code`, `country_code_iso3`, `language`, `currency_name`, `currency_symbol`, `currency_rate`, `is_publish`) VALUES (1, 'Afghanistan', 'AF', 'AFG', '', '', NULL, NULL, 1);
CREATE TABLE `state_master` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `country_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Country name',
    `country_code` VARCHAR(10) NOT NULL DEFAULT '' COMMENT 'Country code' COLLATE 'latin1_swedish_ci',
    `state_code` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'State code' COLLATE 'latin1_swedish_ci',
    `state` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'State' COLLATE 'latin1_swedish_ci',
    `is_publish` TINYINT(1) NOT NULL DEFAULT '1' COMMENT 'Is publish',
    PRIMARY KEY (`id`)
    )
    COLLATE='utf8_general_ci'
    ENGINE=MyISAM
    ROW_FORMAT=DYNAMIC
    AUTO_INCREMENT=1;
 
    INSERT INTO `state_master` (`id`, `country_id`, `country_code`, `state_code`, `state`, `is_publish`) VALUES (1, 1, 'AF', 'BDS', 'Badakhshan', 1);

2) put the below code in your _from.php file.

 make sure pass the state value in hidden field
<?php echo CHtml::hiddenField('hidden_state',$model->state);?>
<div class="control-group">
        <?php echo $form->label($model,'country',array('class'=>'control-label')); ?>
        <div class="controls">
 
        <?php echo $form->dropDownlist($model,'country',UtilityHtml::getCountryData(), array('class'=>'m-wrap large tooltips','data-original-title'=>'Country'),
                    'ajax' => array(
                        'type'=>'POST',
                        'url'=>CController::createUrl('dynamicStates'),
                        'update'=>'#VkUsers_state',
                        'data'=>'js:$(this).serialize()+"&hidden_state='.$model->state.'"',
 
        ))); ?>
        <?php echo $form->error($model,'country',array('class'=>'error_position')); ?>
        </div>
    </div>
<div class="control-group">
        <?php echo $form->label($model,'state',array('class'=>'control-label')); ?>
        <div class="controls">
        <?php echo CHtml::dropDownList('VkUsers[state]','', array(),array('prompt'=>'Select','id'=>'VkUsers_state'),array('class'=>'m-wrap large tooltips','data-original-title'=>'State'))); ?>
        <?php echo $form->error($model,'state',array('class'=>'error_position')); ?>        
        </div>
    </div>

3) write code in controller file

public function actionDynamicStates()
    {
        $data=UtilityHtml::getStateData(isset($_POST['VkUsers']['country']));
        $state = isset($_POST['hidden_state']);
        foreach($data as $value=>$name) {
            $opt = array();
            $opt['value'] = $value;
            if($state == $value) $opt['selected'] = "selected";
            echo CHtml::tag('option', $opt , CHtml::encode($name),true);
        }
        die;
    }

4) create the UtilityHtml in components folder and put the below function

class UtilityHtml extends CHtml{
 
  public static function getCountryData($sel='')
    {
        $data = CountryMaster::model()->findAll();
        $dataOptions = array(''=>'Select Country');
        foreach ($data as $country) {
            $dataOptions[$country->country_code] = $country->country;
        }
        return $dataOptions;
    }
    public static function getStateData($country='')
    {
        $stateData = StateMaster::model()->findAll("country_code = '$country'");
        $dataOptions = array(''=>'Select State');
        foreach ($stateData as $state) {
            $dataOptions[$state->state_code] = $state->state;
        }
        return $dataOptions;
    }
}

5) When you can update the page selected county and state value using a trigger in _form.php file

<?php 
Yii::app()->clientScript->registerScript('countryload','jQuery(function($) {
            $("#VkUsers_country").trigger("change"); 
            $("#VkUsers_state").val(\''.$model->state.'\');
    });
');
?>

I hope it's may be some helpful.

Total 4 comments

#18240 report it
Ankit Modi at 2014/10/04 11:17pm
Reply

Hi Anjith,

=>Please remove the 'multiple'=>true on category drop-down memu

=>pass the subcategory value hidden filed

<?php echo CHtml::hiddenField('hidden_subcategory',$model->subcategory);?>

=> write the js code on _form.php file like

<?php 
Yii::app()->clientScript->registerScript('countryload','jQuery(function($) {
            $("#yourcategoryid").trigger("change"); 
            $("#yoursubcategoryid").val(\''.$model->subcategory.'\');
    });
');
?>
#18238 report it
Anjith at 2014/10/04 12:46pm
I tried this dependent dropdown code, I am new to YII i am seeing the request going to site/index all the time

When ever I change the option in the first dropdown, It is doing ajax validation not calling the function or controller method i defined. If I keep enableAjaxvalidation false, it is not loading any javascript files. View code

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'connecttbl-connect-form',
    // Please note: When you enable ajax validation, make sure the corresponding
    // controller action is handling ajax validation correctly.
    // See class documentation of CActiveForm for details on this,
    // you need to use the performAjaxValidation()-method described there.
    'enableAjaxValidation'=>true,
    'clientOptions' => array(
        'validateOnSubmit'=>true,
    ),
)); ?>
<div class="row">
        <?php echo $form->labelEx($model,'category'); ?>
        <?php echo $form->dropDownList($model,'category', CHtml::listData(Connecttbl::model()->findAll(array('order' => 'category ASC')), 'categoryid', 'category'), array('empty'=>'Select Category', 'multiple'=>true), array(
            'ajax' => array(
                'type' => 'POST',
                'url' => CController::createUrl('/Connect/getSubcategories'),
                'data' => array('category', 'js:this.value'),
                'update' => '#'.CHtml::activeId($model, 'subcategory'),
        ))); ?>
        <?php echo $form->error($model, 'category'); ?>
    </div>
 
    <div class="row">
        <?php echo $form->labelEx($model,'subcategory'); ?>
        <?php echo CHtml::dropDownList('subcategory','', array('multiple'=>true), array(
            'ajax' => array(
                'type' => 'POST',
                'url' => CHtml::createUrl('/Connect/getSubcategories'),
                'data' => array('subcategory', 'js:this.value'),
                'update' => '#'.CHtml::activeId($model, 'crop'),
        )
        )); ?>
        <?php echo $form->error($model,'subcategory'); ?>
    </div>

I defined the below code in controller,

public function actionIndex()
    {
        $model = new Connecttbl();
        if(isset($_POST['ajax'])) {
            if ($_POST['ajax']=='connecttbl-connect-form') {
                echo $_POST['Connecttbl[category]'];
            }
            Yii::app()->end();
        }
 
        if(Yii::app()->user->isGuest)
            $this->redirect('site/index');
        else
        {
 
            $this->render('../site/connect', array('model' => $model));
        }
    }
 
public function actiongetSubcategories()
    {
        $data = Connecttbl::model()->findAll('categoryid=:categoryid', array(':parentid'=>(int)$_POST['Connecttbl[category]']));
        $data = CHtml::listData($data, 'subcategoryid', 'subcategory');
        foreach($data AS $value=>$name)
        {
            echo CHtml::tag('option',
                    array('value'=>$value), CHtml::encode($name),true);
        }
    }
#18035 report it
Ankit Modi at 2014/08/28 11:37pm
code

Yes I always use the code and it's working fine, please provide the error so I can understand.

#18032 report it
wesh at 2014/08/28 11:51am
Code not working

I tried your code above and followed your steps meticulously but it seems there is something wrong.

Have you tested your code?

Leave a comment

Please to leave your comment.

Write new article