Заполнение поля данными

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Заполнение поля данными

Сообщение unknownby »

Есть Виджет
Если выводить всё дерево сразу и без ajax, то после сохранения выведутся все поля в данном виджете. (работает хорошо, но нужна ajax подгрузка).
Если выводить первый уровень дерева и с ajax подгрузкой, то после сохранения и обновления страницы покажутся данные из верхнего уровня, а остальные уровни не покажутся, но из модели передаются все id записей, которые должны отобразиться.
Может кто подскажет, как отредактировать виджет, чтобы выводился весь список данных и работало с ajax подгрузкой.
Первоначальное наполнение виджета идет выборкой верхнего уровня дерева.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

Поставил ради интереса, нормально работает и с аджаксом и без.
Только fontawesome 4.7 добавить и подключить надо, скорее всего вы этого не сделали.
В composer.json добавьте "rmrevin/yii2-fontawesome": "~2.17" и обновите, потом в нужной вьюхе зарегайте \rmrevin\yii\fontawesome\AssetBundle::register($this);
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

yiiliveext писал(а): 2019.12.18, 13:34 Поставил ради интереса, нормально работает и с аджаксом и без.
Только fontawesome 4.7 добавить и подключить надо, скорее всего вы этого не сделали.
В composer.json добавьте "rmrevin/yii2-fontawesome": "~2.17" и обновите, потом в нужной вьюхе зарегайте \rmrevin\yii\fontawesome\AssetBundle::register($this);
У меня PRO версия fontawesome и я подправил её в виджете. У меня всё разворачивается и всё добавляется. Сейчас покажу скриншоты, что нужно в данном вопросе.
1. Выбор элементов http://prntscr.com/qcdotf
2. Вывод элементов, которые были сохранены в БД http://prntscr.com/qcdp7d
3. После сохранения виджет показывает вот что http://prntscr.com/qcdpe2 (то что выбраны все элементы первого уровня это нормально, и при развертывании первого уровня должны быть выбраны и элементы из первого скриншота, но не прописываются они в скрытых полях и поэтому пустые).
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.18, 13:46
3. После сохранения виджет показывает вот что http://prntscr.com/qcdpe2 (то что выбраны все элементы первого уровня это нормально, и при развертывании первого уровня должны быть выбраны и элементы из первого скриншота, но не прописываются они в скрытых полях и поэтому пустые).
Ну так добавьте их в js, там где подгрузка ajax-ом идет.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

yiiliveext писал(а): 2019.12.18, 14:21 Ну так добавьте их в js, там где подгрузка ajax-ом идет.
Я проверял, если без подгрузки ajax-ом сразу вывести весь справочник, то он показывает их как нужно, если работает ajax подгрузка, то внутренние элементы оказываются еще не известными, т.к. в списке их нет. Ajax подгрузка подгружает дочерние элементы в зависимости от parent_id, который выбран.

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

public function actionGetchilds() {
        $node_id = \Yii::$app->request->post('node_id');
        if (!is_numeric($node_id)) {
            $model = MyClass::find()
                ->andWhere(['parent_id' => 0])
                ->orderBy(['id' => SORT_ASC, 'name' => SORT_ASC])->all();
        } else {
            $model =  MyClass::find()
                ->where(['parent_id' => $node_id ])
                ->orderBy(['id' => SORT_ASC, 'name' => SORT_ASC])->all();
        }
        $childsList = [];
        if ($model !== null && is_array($model) && count($model) > 0) {
            foreach($model as $item) {
                $child = MyClass::find()->where(['parent_id' => $item->id])->all();
                if(0 < count($child)){
                    $childsList[] = ['id' => $item->id, 'label' => $item->name, 'items' => []];
                } else {
                    $childsList[] = ['id' => $item->id, 'label' => $item->name];
                }
            }
        }
        return json_encode($childsList);
    }
У меня предположение, что нужно подгружать все ветки, где выбраны элементы. Но не в ajax подгрузке, а в начальной загрузке элементами для виджета. Чтобы он их увидел и отобразил в поле, типо сделана ajax подгрузка без нажатия на "+" в dropdown. Пока что работаю в эту сторону.
Т.е. если выбраны три первые ветки и из первой ветки выбрано три элемента, то нужно первоначально загружать для данной записи все элементы, где parent_id = 0 и дополнительно присоединять запрос, который найдет вложенность в первую ветку всех элементов.
Тогда выдаст весь верхний уровень + второй уровень первого элемента.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

Сейчас выводит хорошо, но нужна рекурсия и чтобы правильно всё же работало.
Вот так сейчас заполняется справочник элементами для первого и второго уровня

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

//наполнение дерева вначале первым уровнем, дальше работает наполнение дочерних элементов, если передается $model  (это данные из модели), которые были сохранены в БД.
public function findTree($model = 0){
        $tree = [];
        $items = MyClass::find()->where(['parent_id' => 0])->all();
        foreach($items as $v){
            $treeObj = [];
            if($model != 0){
            //тут надо как-то рекурсией наполнить, чтобы foreach выбирался пока не будет последний элемент из дерева
            //еще пока не придумал
                foreach($model as $val){
                    if($v->id == $val->parent_id){
                        $treeObj = self::childNodes($v->id);
                    }
                }
            }
            $tree[] = ['id' => $v->id, 'label' => $v->name, 'items' => $treeObj];
        }

        return $tree;
    }

//получение дочерних элементов
    private function childNodes($parentId){
        $treeObj = [];
        $child = MyClass::find()->where(['parent_id' => $parentId])->all();

        foreach($child as $v){
            $treeObj[] = ['id' => $v->id, 'label' => $v->name, 'items' => []];
        }

        return $treeObj;
    }
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.18, 16:11 У меня предположение, что нужно подгружать все ветки, где выбраны элементы. Но не в ajax подгрузке, а в начальной загрузке элементами для виджета. Чтобы он их увидел и отобразил в поле, типо сделана ajax подгрузка без нажатия на "+" в dropdown. Пока что работаю в эту сторону.
Т.е. если выбраны три первые ветки и из первой ветки выбрано три элемента, то нужно первоначально загружать для данной записи все элементы, где parent_id = 0 и дополнительно присоединять запрос, который найдет вложенность в первую ветку всех элементов.
Тогда выдаст весь верхний уровень + второй уровень первого элемента.
Нет, там надо в начале добавить соответствующие hidden input и <li>, котрорых нет в $items и при клике делать проверку на существование.
Это кривой виджет, там надо рефакторить js и исправлять ошибки, сейчас он не будет правильно работать даже без аджакса.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

Порефакторил немного код и дописал загрузку аджаксом выбранных, довольно рабочий вариант получился. Еще часика три потратить бы на доработку, и получится более-менее толковый виджет.
https://i.imgur.com/bgXmQvR.gifv
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

yiiliveext писал(а): 2019.12.18, 23:04 Порефакторил немного код и дописал загрузку аджаксом выбранных, довольно рабочий вариант получился. Еще часика три потратить бы на доработку, и получится более-менее толковый виджет.
https://i.imgur.com/bgXmQvR.gifv
То что нужно. А само решение можно? :D
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Заполнение поля данными

Сообщение maleks »

yiiliveext писал(а): 2019.12.18, 23:04 и получится более-менее толковый виджет.
Когда у категории снимаешь флажок у ее подкатегорий флажок не снимается, этот момент не ожидаемый.
Yii2 universal module sceleton - for basic and advanced templates
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

maleks писал(а): 2019.12.19, 09:32 Когда у категории снимаешь флажок у ее подкатегорий флажок не снимается, этот момент не ожидаемый.
В моем случае такое подходит :D Если расценивать элементы дерева как отличные друг от друга (хоть и находятся в иерархии), а если как категории/подкатегории тогда нужно было бы снимать флажок (т.к. взаимосвязанные данные выходят)
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.19, 08:31 То что нужно. А само решение можно? :D
Временный репо https://github.com/yiiliveext/yii2-tree-dropdown
Как склонируете - маякнете, я удалю.
Вам нужно только заменить файл view.php и в модели реализовать метод getItemLabel($id), который будет возвращать наименование по айди.
Ветки подгружаете по уровням, то есть прилетел айди по аджаксу, делаете SELECT * FROM mytable WHERE parent_id = :id и потом в цикле перебираете полученных детей и проверяете в них наличие собственных детей SELECT * FROM mytable WHERE parent_id = :id LIMIT 1, если есть, то добавляете 'items' => []. По наличию ключа items скрипт определяет необходимость добавления иконки раскрытия ветки (у листьев я ее вообще убрал).
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

yiiliveext писал(а): 2019.12.19, 10:26 Вам нужно только заменить файл view.php и в модели реализовать метод getItemlabel($id), который будет возвращать наименование по айди.
Ветки подгружаете по уровням, то есть прилетел айди по аджаксу, делаете SELECT * FROM mytable WHERE parent_id = :id и потом в цикле перебираете полученных детей и проверяете в них наличие собственных детей SELECT * FROM mytable WHERE parent_id = :id LIMIT 1, если есть, то добавляете 'items' => []. По наличию ключа items скрипт определяет необходимость добавления иконки раскрытия ветки (у листьев я ее вообще убрал).
Круто, спасибо. Скачал.
Я когда подгружаю детей ajax-ом, то делаю запрос с выборкой всего, только без лимита (пока что, т.к. там всего до 10 записей работало быстро), но думаю стоит добавить. Добавление иконки раскрытия переделал, там было если не определено значение, то по-умолчанию минус писало, подправил условие и теперь если не определено значение $items, то пустоту прописывает.
Буду сейчас внедрять правки :D
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.19, 10:37 Добавление иконки раскрытия переделал, там было если не определено значение, то по-умолчанию минус писало, подправил условие и теперь если не определено значение $items, то пустоту прописывает.
Это уже переделано в моем варианте, я написал выше, просто замените view.php
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.19, 10:37 Круто, спасибо. Скачал.
Я когда подгружаю детей ajax-ом, то делаю запрос с выборкой всего, только без лимита (пока что, т.к. там всего до 10 записей работало быстро), но думаю стоит добавить.
Лимит там только у запроса по детям детей, чтобы добавить пустой items, если у них есть дети, иначе не будет ветка раскрываться. Сами дети прилетевшего айди выбираются без лимита
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

Внес пару исправлений, репо пока не удалял
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

yiiliveext писал(а): 2019.12.19, 10:40 Это уже переделано в моем варианте, я написал выше, просто замените view.php
Заменил, всё шикарно. Нашел мини баг. Если убрать все сохранные элементы и нажать сохранить. При этом в контроллере при обновлении просто рендер страницы.

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

public function actionUpdate($id)
    {
	$model = $this->findModel($id);

	if ($model->load(\Yii::$app->getRequest()->post()) && $model->save()) {
            \Yii::$app->session->setFlash($this->flashClass, \Yii::t('main', 'flash.updateSuccess'));
	}

	return $this->render('update', [
		'model' => $model,
	]);
    }
Тогда сам виджет не дает открыть его и внести что-нибудь.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.19, 11:41 Заменил, всё шикарно. Нашел мини баг. Если убрать все сохранные элементы и нажать сохранить. При этом в контроллере при обновлении просто рендер страницы.
Гляньте последние коммиты или скачайте заново view.php, я там исправил. Я просто на эмулированных данных тестил, реальные модели не подключал, так что пишите, если что не так
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Заполнение поля данными

Сообщение unknownby »

yiiliveext писал(а): 2019.12.19, 12:03 Гляньте последние коммиты или скачайте заново view.php, я там исправил. Я просто на эмулированных данных тестил, реальные модели не подключал, так что пишите, если что не так
Я заменил уже новым файлом view.php
Если сохранить пустой список, то дальше не открывается список, нужна перезагрузка страницы.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Заполнение поля данными

Сообщение yiiliveext »

unknownby писал(а): 2019.12.19, 12:12 Я заменил уже новым файлом view.php
Если сохранить пустой список, то дальше не открывается список, нужна перезагрузка страницы.
Там два коммита было, последний решает эту проблему.
А если перезагрузить страницу с пустым списком в поле модели, то работает?
У вас там не pjax часом используется?
Ответить