Visualization tree-multi subcategories as listbox or dropdownlist

5 followers

This wiki article has not been tagged with a corresponding Yii version yet.
Help us improve the wiki by updating the version information.

Do you want to make a listbox or dropdownlist to select one or more categories or sub categories ?

I am sure you have seen that in cms like drupal-wordpress-joomla etc on administrator panel

For example when you create an article you have to select the (sub)categories that it will be appeared, or if you want to make a relation between two or more subcategories you have to do something similar

So, Let's do it in Yii!

We will need the code that generates the tree according to database schema, so check this generate multilever sub categories first

in the same controller (or component) create these methods

public static function getListTreeView() {
        if (empty(self::$catTree)) {
            self::getCategoryTree();
        }
        return self::visualTree(self::$catTree, 0);
 }
 
    private static function visualTree($catTree, $level) {
        $res = array();
        foreach ($catTree as $item) {
            $res[$item['id']] = '' . str_pad('', $level * 2, '-') . ' ' . $item['label'];
            if (isset($item['items'])) {
                $res_iter = self::visualTree($item['items'], $level + 1);
                foreach ($res_iter as $key => $val) {
                    $res[$key] = $val;
                }
            }
        }
        return $res;
    }

now in your views (_form.php) insert this code

1) about select one category by dropdown list (associating categories)

echo $form->labelEx($category,'parent_id');
echo $form->dropDownList($category, 'parent_id', self::getListTreeView(), array('prompt' => 'a prompt')); 
echo $form->error($category,'parent_id');

2) about Select multi categories by listbox (for example an article has many categories)

$selected = array();
 
foreach ($article->Categories as $item) {
    $selected[$item->category_id]=array('selected' => 'selected');
}
 
$data = self::getListTreeView(); 
$htmlOptions = array('multiple' => 'true', 'options' => $selected);
 
echo $form->labelEx($model, 'listCategories');
echo $form->error($model, 'listCategories'); 
echo $form->listBox($model, 'listCategories', $data, $htmlOptions);

Note: article is an implemented model that has been associated with categories

The class of article must contains a relation like that

public function relations()
{
    return array(
         ...
'Categories' => array(self::MANY_MANY, 'Category', 'article_category(category_id, article_id)'),
    );
}

Thats it!

Total 4 comments

#14425 report it
KonApaz at 2013/08/10 05:13pm
Re: Re listBox

Hi again seenivasan

I think your code works for one lever of category (showing all sub...sub (level1 level 3 level 3...) as a first category lever)

for example this wiki introduced tree-multi subcategories, so displays the tree as:

categoryA
-- subcategory (lever 1)
---- subsubcategory (lever 2)
-- subcategory (lever 1)
subcategoryB
-- subcategory (lever 1)
---- subcategory (lever 2)
------ subcategory (lever 3)

Please correct me if I am wrong Thanks :)

#14322 report it
seenivasan at 2013/08/04 03:39pm
Re listBox

Dear Friend

Considering the relation between articles and catagories as Many-Many, we can allow the user to select the an article above which we can display the catagories to which the article belongs.

echo CHtml::listBox('somevalue',"",CHtml::listData(Article::model()->findAll(),'id','title',function($model){
       $cats=$model->catagories;
       $arr=array();
       foreach($cats as $cat)
             $arr[]=$cat->name;
       return implode(",",$arr);
}),array("multiple"=>true));
#14315 report it
KonApaz at 2013/08/04 12:10pm
RE: CHtml::listData()

Thanks for your comment, seenivasan

Could you give us a real example of that on the same category-article? I can't imagine how could set the listData to achieve that

Did you think to do the same thing for listBox ?

#14312 report it
seenivasan at 2013/08/04 11:06am
Thanks

Dear My Friend

Thanking you for sharing the tip.

I think that CHtml::listData() does the same magic.

We can declare the fourth parameter groupField in the function.

Let us have a relation .

We have clauses which belong to a topic.

echo CHtml::dropDownList('some','',CHtml::listData(Clause::model()->findAll(),'id','title','topic.title'));

We have a title of topic as groupField . Under each title we have its clauses displayed.

Regards.

Leave a comment

Please to leave your comment.

Write new article