GridView + древовидное представление данных

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
GaryFreeman
Сообщения: 2
Зарегистрирован: 2015.05.21, 17:11

GridView + древовидное представление данных

Сообщение GaryFreeman » 2015.05.21, 17:26

Добрый день! Реализую движок интернет магазина, встала задача реализовать список категорий в виде "псевдо-дерева", как в Wordpress, т.е.:
Изображение
Как видно из скриншота, категории Wallpapers, Иллюстации и Разное являются подкатегориями категории Вдохновение. Мне необходимо сделать что-то вроде того же. Пока сделал это через relations и рекурсивную функцию:

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

    /**
     * Lists all Category models.
     * @return mixed
     */
    public function actionIndex()
    {
        return $this->render('index', [
            'categories' => $this->_getCategoriesList(true, Yii::$app->params['category.list.indent']),
        ]);
    }
    /**
     * Получить список всех категорий
     */
    protected function _getCategoriesList($withModels = false, $indent)
    {
        if (!$withModels) {
            $list = [
                '' => Yii::t('app', '== Не выбрано =='),
            ];
        } else {
            $list = [];
        }

        $rootCategories = Category::find()->where(['parent' => null])->all();
        foreach ($rootCategories as $cat) {
            if ($withModels) {
                $list[$cat->id] = $cat;
            } else {
                $list[$cat->id] = $cat->title;
            }
            $list = $list + $this->_buildCategoriesListLevel($cat, $withModels, $indent);
        }

        return $list;
    }

    /**
     * Получает один уровень списка категорий. Рекурсия.
     */
    protected function _buildCategoriesListLevel($rootCategory, $withModels, $indent)
    {
        $list = [];

        foreach ($rootCategory->childrenCategories as $cat) {
            if ($withModels) {
                $cat->title = $indent . $cat->title;
                $list[$cat->id] = $cat;
            } else {
                $list[$cat->id] = $indent . $cat->title;
            }
            if (count($cat->childrenCategories) > 0) {
                $sublist = $this->_buildCategoriesListLevel($cat, $withModels, $indent);
                foreach ($sublist as $k => $v) {
                    if ($withModels) {
                        $v->title = $indent . $v->title;
                        $list[$k] = $v;
                    } else {
                        $list[$k] = $indent . $v;
                    }
                }
            }
        }

        return $list;
    }
В результате получается список моделей, который я вывожу простым foreach'ом в виде таблицы:

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

    <?php if (count($categories)): ?>
    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <th width="75"><?= reset($categories)->getAttributeLabel('id') ?></th>
                <th><?= reset($categories)->getAttributeLabel('title') ?></th>
                <th width="100">&nbsp;</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($categories as $cat): ?>
            <tr>
                <td><?= $cat->id ?></td>
                <td><?= $cat->title ?></td>
                <td align="center">
                    <a href="<?= Url::to(['category/view', 'id' => $cat->id]) ?>"><span class="glyphicon glyphicon-eye-open"></span></a>
                    <a href="<?= Url::to(['category/update', 'id' => $cat->id]) ?>"><span class="glyphicon glyphicon-pencil"></span></a>
                    <a href="<?= Url::to(['category/delete', 'id' => $cat->id]) ?>" data-method="post"
                        data-confirm="<?= \Yii::t('app', 'Вы уверены, что хотите удалить эту категорию?') ?>">
                        <span class="glyphicon glyphicon-trash"></span>
                    </a>
                </td>
            </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
    <?php else: ?>
    <p class="bg-info"><?= Yii::t('app', 'Ничего не найдено.') ?></p>
    <?php endif; ?>
И выглядет все это примерно так:
Изображение
Но это не совсем хорошо, т.к. пропадает возможности GridView: сортировка, фильтрация и пагинация. При сортировке, естественно, будет обычный вывод с учетом сортировки, но в качестве сортировки "по-умолчанию" хотелось бы именно иерархический вид.

Собственно вопрос: как мне реализовать все это при помощи GridView? Заранее благодарю за помощь!

psevdo
Сообщения: 96
Зарегистрирован: 2013.04.10, 11:10

Re: GridView + древовидное представление данных

Сообщение psevdo » 2015.05.25, 12:02

Мне вот тоже нужно примерно такое сделать. Тоже тему создавал. Посоветовали расширить виджет.

arogachev
Сообщения: 52
Зарегистрирован: 2014.09.09, 14:32

Re: GridView + древовидное представление данных

Сообщение arogachev » 2015.05.25, 12:13

Принципиально ли это совмещать с GridView? Может быть сделать отдельным виджетом?
Мой профиль на Github

psevdo
Сообщения: 96
Зарегистрирован: 2013.04.10, 11:10

Re: GridView + древовидное представление данных

Сообщение psevdo » 2015.05.25, 12:20

Дело в том, что нужны стандартные возможности этого виджета, н-р сортировка

dmg
Сообщения: 667
Зарегистрирован: 2012.10.15, 03:09

Re: GridView + древовидное представление данных

Сообщение dmg » 2015.05.25, 12:37

вариант дерева принципиален? с nested set сортировка удобней.

psevdo
Сообщения: 96
Зарегистрирован: 2013.04.10, 11:10

Re: GridView + древовидное представление данных

Сообщение psevdo » 2015.05.25, 14:00

dmg писал(а):вариант дерева принципиален? с nested set сортировка удобней.
До этого времени даже не знал что это такое)

GaryFreeman
Сообщения: 2
Зарегистрирован: 2015.05.21, 17:11

Re: GridView + древовидное представление данных

Сообщение GaryFreeman » 2015.05.25, 22:09

dmg писал(а):вариант дерева принципиален? с nested set сортировка удобней.
Большое спасибо за совет, буду копать в эту сторону!

Ответить