cascadedropdown Easy creating of dependent dropdownlists

  1. Requirements
  2. Usage
  3. A) Two activeDropDownLists
  4. B) Three dropDownLists
  5. Resources

This simple to use extension uses the jQuery plugin jquery-cascade to populate the data of a dependent dropdownlist by a ajax/getJSON-call.

It works with the standard CHtml::activeDropDownList or the CHtml/CActiveForm::dropDownList - no extra dropdown-components needed.

Requirements

Developed with Yii 1.1.11, not tested with other releases

Usage

Extract the zip-file into your to protected/extensions directory. Import the component in config/main.php

// autoloading model and component classes
'import'=>array(
    'application.models.*',
    'application.components.*',
......
    'ext.cascadedropdown.ECascadeDropDown',

or use

Yii::import('ext.cascadedropdown.ECascadeDropDown');

in your controller instead.

A) Two activeDropDownLists

Assume you have a model where you want to set the province and the city. But the city dropdown options depend on the selected province.

Your view

Create your dropdownlists like you would do without this extension and add a line of code to make them "cascade". It's important to assign a unique id in the htmlOptions of the dropdownlists.

...

//add the province dropdownlist
$provinceItems = CHtml::listData(Province::model()->findAll(), 'id', 'name');
echo CHtml::activeDropDownList($model, 'province', $provinceItems, array('id'=>'id_province','prompt'=>'-')); 	

//add the cities dropdownlist, show only the items of the current province
$cityItems = CHtml::listData(City::model()->findAll('province=:province', array(':province'=>model->province)), 'id', 'name');	
echo CHtml::activeDropDownList($model, 'city', $cityItems, array('id'=>'id_city','prompt'=>'-')); 	


//----------- the additional part ------------------------------------
//Build the dependency/cascade with province as master
//Show the text 'Loading cities ...' on waiting for the data.
//Update the city-data through the ajax-url: Yii::app()->createUrl('site/citydata')
ECascadeDropDown::master('id_province')->setDependent('id_city',array('dependentLoadingLabel'=>'Loading cities ...'),'site/citydata');	

...

A change of the province-dropdownlist will lead to a ajax-call to populate the corresponding cities. So you have to create the action 'citydata' in the controller 'site'. In this function you can use some static ECascadeDropDown helper method to generate the json-data response. See the sourcecode for details.

Your controller
class SiteController extends Controller
{

 public function actionCitydata()
 {
   //check if isAjaxRequest and the needed GET params are set 
   ECascadeDropDown::checkValidRequest();

   //load the cities for the current province id (=ECascadeDropDown::submittedKeyValue())
	$data = City::model()->findAll('province=:province', array(':province'=>ECascadeDropDown::submittedKeyValue());

   //Convert the data by using 
   //CHtml::listData, prepare the JSON-Response and Yii::app()->end 
   ECascadeDropDown::renderListData($data,'id', 'name');
 }

That should be all ... Take a look at the comments in the source for more options.

B) Three dropDownLists

If you want you can cascade three (or more) dropdownlists. Below is a ready to use example you can copy/paste for testing. It shows more ECascadeDropDown helper functions and uses the same controlleraction for all data-requests. If you want so, you have to set the controllerRoute in the master() method instead of the setDependent() method. But in most cases I would prefer to use extra controlleractions for each dropdownlist.

Your view

Combine 3 dropdownlists:

$items = array('mobile'=>'Mobile','printers'=>'Printers');
    echo CHtml::dropDownList('id_type','', $items, array('prompt'=>'-'));
    echo CHtml::dropDownList('id_company', '', array());
    echo CHtml::dropDownList('id_article', '', array());

    //handle all data response in one controller action
    ECascadeDropDown::master('id_type','site/selectarticle') //'controllerId/actionId'
                      ->setDependent('id_company') //master for id_article with default options
                      ->setDependent('id_article', //with custom labels
                                      array('dependentStartingLabel'=>'Select article','dependentLoadingLabel'=>'Loading articles...'));
Your action in the SiteController
public function actionSelectArticle()
{
ECascadeDropDown::checkValidRequest();  //comment to debug this url in the browser

$data = array(
	'id_type' => array(
		'mobile' => array('company_apple'=>'Apple','company_samsung'=>'Samsung'),
		'printers' => array('company_hp'=>'HP','company_brother'=>'Brother'),
	),

	'id_company' => array(
		'company_apple' => array('imac'=>'iMac','iphone'=>'iPhone','ipad'=>'iPad','ipod'=>'iPod'),
		'company_samsung' => array('galaxy'=>'Galaxy','wave'=>'Wave'),
		'company_hp' => array('laserjet'=>'Laserjet','photosmart'=>'Photosmart'),
		'company_brother' => array('hlserie'=>'HL Serie','mwserie'=>'MW Serie'),
	)
);

$masterId = ECascadeDropDown::submittedMasterId();  //master dropdownlist id_type or id_company
$masterKey = ECascadeDropDown::submittedKeyValue(); //the current key of the master
//$dependentId = ECascadeDropDown::submittedDependentId(); if you need the dependent id

if(isset($data[$masterId][$masterKey]))
	ECascadeDropDown::renderArrayData($data[$masterId][$masterKey]); //with Yii::app()->end()


ECascadeDropDown::renderEmptyData('-');
}

Resources

9 0
20 followers
1 195 downloads
Yii Version: 1.1
License: BSD-2-Clause
Category: User Interface
Developed by: Joblo
Created on: Sep 29, 2012
Last updated: 5 years ago

Downloads

show all

Related Extensions