Вложенный список

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
linuxoid10
Сообщения: 133
Зарегистрирован: 2012.11.24, 14:02

Вложенный список

Сообщение linuxoid10 »

Доброго времени суток! Как в листбох поместить вложенный список?

Пример.

Есть таблица cateories
id | title | parent_id
1 категория 1 0
2 подкатегория 1 1
3 подкатегория 2 1
4 категория 2 0
5 категория 3 0
6 подкатегория 3 5

как поместить в листбокс сохраняя структуру?
Zlatov
Сообщения: 56
Зарегистрирован: 2014.09.04, 17:58

Re: Вложенный список

Сообщение Zlatov »

Код: Выделить всё

<?php echo $form->dropDownList(
            $model,
            'parent_id',
            CHtml::listData(
                $models,
                'id',
                function($models) {
                    return $models['separator'] . CHtml::encode($models['header']);
                }
            ),
            array('empty' => '', 'encode' => false)
        ); ?>
Как видите я вставил дополнительные данные в dropDownList ($models['separator'])
$models['separator'] - это отступ слева пробелами и спец символами, картинкой нагляднее:
Изображение
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Вложенный список

Сообщение Loveorigami »

Добрый день.
Пытаюсь получить вид списка, как у вас - но у меня почему-то получается он плоским.

Код: Выделить всё

        
$models = Category::model()->findAll();

        echo $form->dropDownList($model, 'pid',
                CHtml::listData(
                             $models, 'id', function($models) {
                      return '|_' . CHtml::encode($models['menu_name']);
                  }), array('empty' => '(Select a category)')
        );

 
не могли бы вы подсказать, что у меня не так.
Да и как сделать такой красивый сепаратор, как у вас.
Zlatov
Сообщения: 56
Зарегистрирован: 2014.09.04, 17:58

Re: Вложенный список

Сообщение Zlatov »

Чтобы сделать сепаратор - нужно знать уровень вложенности каждого элемента.
У вас в таблице нет таких данных.
Чтобы получить уровень вложенности нужно рекурсией обойти все элементы от корня к родителям, вычислять и запоминать уровень в дополнительное поле $models[id] = array('level' => $level);
А так же с помощью данных о уровне создавать ещё одно дополнительное поле $models[id] = array('separator' => $separator);

Да блин, лучше вот скриптик почитайте:

Код: Выделить всё

    /* Получение древовидного списка */
    // Вызов $tree = Page::tree(array('id','parent_id'),array('sid','header','title'));
    public static function tree($keys,$select,$order=false,$notthis=false) {
        $list = array();
        list($nameid,$nameparentid) = $keys; // Имена ключевых полей по которым будет составлятся дерево
        $select = array_unique(array_merge($keys,$select)); // Для criteria список полей

        $criteria = new CDbCriteria;
        $criteria->select = implode(', ',$select);
        if ( $notthis !== false ) {
            $criteria->condition = 'id <> :id';
            $criteria->params = array(':id'=>$notthis);
        }
        $class = get_called_class();
        $models = $class::model()->findAll($criteria);

        //echo '<pre>';
        //print_r($criteria);
        //echo '</pre>';


        foreach ($models as $value) {
            $line = array();
            foreach ($select as $val) {
                $line[$val] = CHtml::encode($value->$val);
                //str_replace(array('"','<'),array('"','<'),str_replace('&','&',$row[$val]));
            }
            $list[$value->id] = $line;
        }

        $tree = array();
        $level = 0;
        $parentid[$level] = null;
        while ($level !== -1) {
            $mode = each($list);
            if ( $mode !== false ) {
                if ( $mode['value'][$nameparentid] == $parentid[$level] ) {
                    $mode['value']['level'] = $level;
                    $tree[] = $mode['value'];
                    unset($list[$mode['key']]);
                    $levelup = false;
                    $temp = $list;
                    foreach ($temp as $val) {
                        if ( $val[$nameparentid] == $mode['key'] ) {
                            $levelup = true;
                        }
                    }
                    if ( $levelup ) {
                        $level++;
                        $parentid[$level] = $mode['key'];
                        reset($list);
                    }
                }
            } else {
                $level--;
                reset($list);
            }
        }
        foreach ($tree as $key => $val) {
            $separator = '';
            for ($i=0; $i<$val['level']; $i++) {
                $separator .= "&nbsp;&nbsp;&nbsp;&nbsp;";
            }
            $separator .= ($val['level']!==0)?((isset($tree[$key+1]))&&($val['level']==$tree[$key+1]['level']))?'┣ ':'┗ ':'';
            $tree[$key]['separator'] = $separator;
        }
        
        //echo '<pre>';
        //print_r($tree);
        //echo '</pre>';
        return $tree;
    } 
Ответить