Grouped drop-down list


I would like to create a drop-down list containing data from a table in the database.

The table contains property types as follows

id   title        parent_id

1    residential   0

2    commercial    0

3    land          0

4    apartment     1

5    shop          2

From the above i would wish to create a grouped drop-down list as follows




  • apartment


  • shop


so far i have been able to create a grouped drop-down list with parent id numbers as the group titles but i would like it to appear as above…

thanks in advance… :)

Hi kelvo, welcome to the forum.

Would you please post your current code to get an array for the list?

here is the code


	$data=CHtml::listData($propertType, 'id', 'title' ,'parent_id');

	echo $form->labelEx($model,'property_type'); 

	echo $form->dropDownList($model,'property_type',$data); 

it produces a list with the parent id’s as the group names

I see.

Maybe something like this:

// PropertyType.php


public function relations()


	return array(

		'parent' => array(self::BELONGS_TO, 'PropertyType', 'parent_id', 'condition' => 't.parent_id <> 0'),




// view



        $data=CHtml::listData($propertType, 'id', 'title' ,'parent.title');


@softark, interesting, but don’t you think that, that way, you’d retrieve parent elements that have child items (if I understood correctly, ‘land’ would not be retrieved).

Maybe rather:


[*]have a HAS_MANY relation on parent_id,

[*]the $data would have only items with parent_id = 0, and put them into OPTGROUP tags

[*]loop into the $data array, and foreach $data check the HAS_MANY relation (call it ‘children’ for instance), and if the array is not empty, retrieve children, and put them in OPTION tags.


in order to have something like


  <?php foreach($data as $parent) { ?>

  <optgroup label="<?php echo $parent->title; ?>">

    <?php foreach($parent->children as $child) { ?>

    <option value="<?php echo $child->id; ?>"><?php echo $child->title; ?></option>

    <?php } ?>


  <?php } ?>



You mean that an optionGroup without a member (e.g. ‘land’) will not be listed, don’t you?

Yes, you are right.

So, when you want an empty group to be listed …

public function relations()


	return array(

		'children' => array(self::HAS_MANY, 'PropertyType', 'parent_id'),




$parents = PropertyType::model()->findAll('parent_id = 0');

$data = array();

foreach($parents as $parent)


	$sub_data = array();

	foreach($parent->children as $child)


		$sub_data[$child->id] = $child->title;


	$data[$parent->title] = $sub_data;


echo $form->labelEx($model,'property_type');

echo $form->dropDownList($model,'property_type',$data); 

@softark you’re a genius. I didn’t know that dropDownList can output OPTGROUPs. Thanks a lot for the valuable tip.

Ah, please don’t be kidding.

I learned it from the source code of CHtml::listData() and CHtml::listOptions(). :)

No I wasn’t flattering or kidding. Let’s settle on “Yii keeps on surprising me” :D

this works but the residential and commercial fields appear twice, as fields and as group titles

after going through your suggestion i got it to work with this piece of code


	$data=CHtml::listData($propertType->with('parent')->findAll(array('condition'=>'>2')), 'id', 'title','parent.title');

	echo $form->dropDownList($model,'property_type',$data);  

Thanks guys…

But if anyone has a better way to do this please don’t hold back

hey gabrielk,

sure just drop me your contacts.


i need to make the same thing in my code, present grouped drop down list

i have class (id, name, section), i need to present the classes grouped by section in a drop downlist

here is my code

public function actionGetClassByCycle(){


	$model=Usersectionsecurity::model()->findAll('Group_Code=\'' . $_POST['CycleID'] . '\'');


	$data=CHtml::listData($model,'Class_Code', 'A_Class_Desc', 'E_Section_Desc');



        echo "<option value=''>Select Class </option>";

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


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



i add E_Section_Desc at the end of the listData, but there is not result at all

thanks in advance