GridView зависимый от select

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

GridView зависимый от select

Сообщение Fixpix »

Всем привет!

Я абсолютный новичок и yii2 и в php, но есть стремление изучать... очень нужна ваша помощь...

Мне не понятно как я могу привязать селект к гридвью, то есть чтобы при выборе покупателя, таблица бы обновилась со всеми заказами этого покупателя через pjax.

Select

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

<?php
            try {
                echo Select2::widget([
                    'id'=>'customer',
                    'name' => 'customer',
                    'data' => \yii\helpers\ArrayHelper::map(\app\models\Customers::find()->all(), 'id', 'name'),
                    'maintainOrder' => true,
                    'options' => [
                        'placeholder' => 'Customer ...',
                        'multiple' => true,
                    ],
                    'pluginOptions' => [
                        'tags' => true,
                        'maximumInputLength' => 10
                    ],
                ]);
            } catch (Exception $e) {
                throw new RuntimeException ($e->getMessage());
            }
            ?>
JS

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

$js = <<<JS
    $("#customer").on('change', function()
        {
            const customer = $('#customer').val();
            
            if (customer !== 0){
                $.ajax({
                    url: 'index.php?r=orders',
                    dataType: 'html',
                    method: 'GET',
                    data: {id: customer},
                    success: function (data, textStatus, jqXHR) {
                        $.pjax.reload({container:'#pjaxContainer'});
                        console.log('success');
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log('An error occured!');
                    }
                });
            }
        }
    );
JS;
$this->registerJs($js, yii\web\View::POS_READY);
GridView

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

<?php \yii\widgets\Pjax::begin([
        'id'=>'pjaxContainer',
    ]); ?>
    <?php
    try {
        echo GridView::widget([
            'dataProvider' => $dataProvider,
            'filterModel' => $searchModel,
            //'rowOptions' =>$searchModel->id,
            'headerRowOptions'=>['class'=>'kartik-sheet-style'],
            'columns'=>[
                ['class' => 'yii\grid\SerialColumn'],
                ['class' => 'yii\grid\CheckboxColumn'],

                'id',
                'quantity',
                'products_id',
                'customers_id',
                [
                    'attribute' => 'products_id',
                    'label' => 'Name of product',
                    'value' => 'products.name',
                ],

                [
                    'attribute' => 'products_id',
                    'label' => 'Description',
                    'value' => 'products.description',
                ],

                [
                    'attribute' => 'customers_id',
                    'label' => 'Name',
                    'value' => 'customers.name',
                ],

                [
                    'attribute' => 'customers_id',
                    'label' => 'Lastname',
                    'value' => 'customers.lastname',
                ],
            ],
        ]);
    } catch (Exception $e) {
        throw new RuntimeException($e->getMessage());
    }
    ?>
    <?php \yii\widgets\Pjax::end() ?>
Controller

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

public function actionIndex()
    {
        $searchModel = new OrdersSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }
примерно представляю что должен получить id, Yii::$app->request->get('id'), но не могу сообразить как...
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

При генерации CRUD через gii модуль Yii2 получается сразу то, что вам надо. Там есть форма поиска, изменяя любое поле фильтра, обновляется список через pjax. Осталось посмотреть как там работает и воспроизвести как вам надо.
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

В ajax вы посылаете data: {id: customer}, , а чтобы actionIndex вернул нужный вам dataProvider, вам нужно в searchModel установить customers_id . Т.е. нужно посылать data: {ИМЯ_ПОЛЯ_customers_id: customer},

ИМЯ_ПОЛЯ_customers_id - формируется как \yii\helpers\Html::getInputName($searchModel, 'customers_id')

После того, как вы это отправите, вы получите html, который необходимо вставить вместо текущего Grid. А вы зачем то pjax перезагружаете с по текущему url. Используете pjax и ajax, получается масло масленное. Надо бы через pjax сразу нужный url с GET параметрами сформировать и он всю подмену сделает сам. Это вам сюда https://github.com/defunkt/jquery-pjax#usage

И проблемы будут наверное в $("#customer").on('change', function(), правильное использование
$('#customer').on('select2:change', function()...
https://select2.org/programmatic-control/events
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

И зря вы взяли картика модули. Да они работаю, но в 99% они работают не так как вам нужно. Пока вы заставите их работать как вам нужно, поймёте как работает изначальный код JS библиотеки, например Select2. Окажется, что у картика он устарел, документация не соотвествует, вы наткнётесь на баги, которые в select2 уже решены. Придётся устанавливать и разбираться с Select2. Лучше сразу брать голую JS библиотеку и согласно её API интегрировать её в представления Yii2. Поймете как работают многие вещи...
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

yiijeka писал(а): 2018.08.02, 08:21 И зря вы взяли картика модули. Да они работаю, но в 99% они работают не так как вам нужно. Пока вы заставите их работать как вам нужно, поймёте как работает изначальный код JS библиотеки, например Select2. Окажется, что у картика он устарел, документация не соотвествует, вы наткнётесь на баги, которые в select2 уже решены. Придётся устанавливать и разбираться с Select2. Лучше сразу брать голую JS библиотеку и согласно её API интегрировать её в представления Yii2. Поймете как работают многие вещи...
Спасибо за ваш ответ. Картик взял потому что верстал проект с его использованием... по поводу библиотеки, скорей всего вы правы, надо попробовать.
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

yiijeka писал(а): 2018.08.02, 08:15 В ajax вы посылаете data: {id: customer}, , а чтобы actionIndex вернул нужный вам dataProvider, вам нужно в searchModel установить customers_id . Т.е. нужно посылать data: {ИМЯ_ПОЛЯ_customers_id: customer},

ИМЯ_ПОЛЯ_customers_id - формируется как \yii\helpers\Html::getInputName($searchModel, 'customers_id')

После того, как вы это отправите, вы получите html, который необходимо вставить вместо текущего Grid. А вы зачем то pjax перезагружаете с по текущему url. Используете pjax и ajax, получается масло масленное. Надо бы через pjax сразу нужный url с GET параметрами сформировать и он всю подмену сделает сам. Это вам сюда https://github.com/defunkt/jquery-pjax#usage

И проблемы будут наверное в $("#customer").on('change', function(), правильное использование
$('#customer').on('select2:change', function()...
https://select2.org/programmatic-control/events
не могли бы вы немного больше разжевать про searchModel, что именно надо добавить и почему так, мои познания пока не очень сильны к сожалению.
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

у вас есть класс OrdersSearch. Он наследуется от Orders скорее всего...

Напишите в OrdersSearch

public $customers_id = '123';


и в GridView у вас будут данные только с customers_id равным '123'... Теперь подумайте что вы сделали и что произошло.

Теперь удалите public $customers_id = '123'; и подумайте, как установить $searchModel->customers_id = 123 в public function actionIndex()

После этого я думаю вы поймёте механизм работы searchModel
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

Я добавил в контроллере одну строчку $dataProvider->query->andWhere('customers_id'=>'123']);

это рабочий вариант, но не совсем уверен что правильный..
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

Он мне сейчас ничего не показывает, что логично, но и при выборе селекта тоже ничего...

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

public function actionIndex()
    {
        $custId = Yii::$app->request->get('id');

        $searchModel = new OrdersSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        $dataProvider->query->andWhere(['id'=>$custId]);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }
посмотрел в Network, он мне возвращает правильно, не не рендерит
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

Yii::$app->request->get('id'); не надо делать. Заполнение GET происходит в $searchModel->search(Yii::$app->request->queryParams);

Дальше в метод провалитесь и увидете там ->load(....)...

И $_GET у вас не ['id'] , а ['customer'] судя по Select2
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

Привет,

вообще сделал через _search вьюшку:

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

$js = <<< JS
    $("#pjaxFilter").on("pjax:end", function() {
        $.pjax.reload({container:"#pjaxContainer"});
    });
JS;
$this->registerJs($js, yii\web\View::POS_READY);
?>

<?php yii\widgets\Pjax::begin(['id' => 'pjaxFilter']) ?>
    <?php $form = ActiveForm::begin([
        'options' => ['data-pjax' => true ],
        'action' => ['index'],
        'method' => 'get',
    ]);
?>

<?= $form->field($model, 'name')
            ->label(false)
            ->widget(\kartik\select2\Select2::class, [
                'name' => 'Customers',
                'data' => ArrayHelper::map(Customers::find()->all(), 'name', 'name'),
                'options' => [
                    'placeholder' => 'Customers...',
                    'multiple' => true,
                ],
            ]) ?>

        <div class="form-group">
            <?= Html::submitButton('Искать', ['class' => 'btn btn-primary']) ?>
        </div>
<?php ActiveForm::end(); ?>
<?php Pjax::end() ?>
На главной вывожу:

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

<?= $this->render('_search', [
    'model' => $searchModel,
]) ?>
сейчас вроде все работает, но если только использовать нормальную выборку... 'multiple' => true не работает, после выбора второго покупателя, не выводит ничего...

и не знаю как сделать динамический селект, сейчас работает по нажатию кнопки "искать".
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

'multiple' => true - это значит посылается массив значений, т.е. в rules валидации в OrdersSearch нужно прописать, что там будет массив
https://www.yiiframework.ru/forum/viewtopic.php?t=42816

> и не знаю как сделать динамический селект, сейчас работает по нажатию кнопки "искать".
Pjax нужно правильно обернуть - открывать до _search, а закрывать после GridView
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

Добавил правило, но ничего не изменилось... [['name'], 'each', 'rule' => ['string','max' => 100]]
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

У вас же
->widget(\kartik\select2\Select2::class, [
'name' => 'Customers',

Правило должно выглядить так тогда:
[['Customers'], 'each', 'rule' => ['string','max' => 100]]
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

даже если менять на Customers, ничего не меняется
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

Потому, что Customers скорее всего не используется в методе $searchModel->search()
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

yiijeka писал(а): 2018.08.07, 10:43 Потому, что Customers скорее всего не используется в методе $searchModel->search()
только теперь еще и ошибка Getting unknown property

я совсем запутался, блин я наверно туплю сильно, извиняюсь...
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: GridView зависимый от select

Сообщение yiijeka »

Ошибка, потому что Customers не определено в OrdersSearch :)

public $Customers;

Быстрое решение:
Верните

[['name'], 'each', 'rule' => ['string','max' => 100]]

и
<?= $form->field($model, 'name')
->label(false)
->widget(\kartik\select2\Select2::class, [
'name' => 'Customers', << ---- уберите эту строчку
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

он мне все равно возвращает ?OrdersSearch[Customers]=&OrdersSearch[Customers][]=Alex&OrdersSearch[Customers][]=Vasya&
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: GridView зависимый от select

Сообщение Fixpix »

Controller

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

public function actionIndex()
    {
        $searchModel = new VorstufeSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        if (Yii::$app->request->isAjax || Yii::$app->request->isPjax){
            return $this->renderPartial('index', [
                'searchModel' => $searchModel,
                'dataProvider' => $dataProvider,
            ]);
        }
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }
Закрыто