Grouped drop-down list

Hi,

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

[list=1]

[*]land

[*]residential

  • apartment

[*]commercial

  • shop

[/list]

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




        $propertType=PropertyType::model()->findAll();

	$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

...

        $propertType=PropertyType::model()->with('parent')->findAll();

        $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:

[list=1]

[*]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.

[/list]

in order to have something like


<select>

  <?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 } ?>

  </optgroup>

  <?php } ?>

</select>

@bennouna

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(). :)

http://www.yiiframework.com/doc/api/1.1/CHtml#listData-detail

http://www.yiiframework.com/doc/api/1.1/CHtml#listOptions-detail

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




        $propertType=PropertyType::model();

	$data=CHtml::listData($propertType->with('parent')->findAll(array('condition'=>'t.id>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.

regards,

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