Как сделать динамическую подгрузку данных при выборе пункта из выпадающего списка формы в Yii2?

При заполнении формы мне нужно реализовать одно из полей с выпадающим списком пользователей, при нажатии на пункт списка подгружается и выводится таблица с данными конкретного пользователя.

AJAXом пользоваться не умею, попробовал сделать через PJAX. Получилось частично. Создал форму с выпадающим списком и кнопкой, обернул её в PJAX - при нажатии на кнопку все работает как надо, обновляется только поле между тегами PJAX (код ниже)

<?= date('Y-m-d H:i:s',(new DateTime())->getTimestamp()); ?> //тестовый код для отслеживания обновления областей страницы
    
    <?php Pjax::begin(); ?>    

    <?php $form = ActiveForm::begin(['options' => ['data-pjax' => true]]); ?> 
    
    <?= $form->field($model, 'field1')
->dropDownList(\yii\helpers\ArrayHelper::map(User::find()->all(), 'id', 'username')); ?> 
    
    <?php echo Html::submitButton('Пробуем', ['class' => 'btn btn-info']) ?>
    
    <?= date('Y-m-d H:i:s',(new DateTime())->getTimestamp()); ?>

    <?php    ActiveForm::end(); ?>
    
        <?php if ($model->field1): ?>

    //выводимые данные
    <div class="row">
        <div class="col-lg-4">
           <?= DetailView::widget([
                'model' => User::findIdentity($model->field1),
                'options' => [
                    'class' => 'table table-no-border table-condensed',
                ],
                'attributes' => [
                    [
                    'attribute' => 'username',
                    'label' => 'Логин',
                    ],
                    [
                    'attribute' => 'building',
                    'label' => 'Корпус',
                    ],
                    [
                    'attribute' => 'room',
                    'label' => 'Кабинет',
                    ],
                ],
           ]); ?>
        </div>
        </div>
    
        <?php endif; ?>
    
    <?php Pjax::end();?>

Хорошо, но это не совсем то, нужно без кнопки. Пошарил в сети, нашел решение, но при попытке реализации отправки формы таким образом:
<?= $form->field($model, 'field1')
->dropDownList(\yii\helpers\ArrayHelper::map(User::find()->all(), 'id', 'username'), ['onchange' => 'this.form.submit()']); ?>

т.е. без кнопки, почему-то обновляется вся страница.

Как лучше сделать правильно?
  • Вопрос задан
  • 2544 просмотра
Решения вопроса 3
@zayac_agito
1) Поставить ajax клик на пункт меню
2) По событию клика, загрузить, через ajax, данные из yii2 (создай для этого action в контроллере)
3) Разместить данные в html элемент на странице, по завершению запроса
Ответ написан
Можно сделать GET-запросом, но учитывая activeForm, мне ближе делать это через POST
Форма
<?php $form = ActiveForm::begin([
    'id' => 'get_users', //Добавляем ID для отслеживания в JS
    'action' => \yii\helpers\Url::to(['ВАШ ЭКШН']) //Добавляем адрес, к которому пойдет запрос, если он отличается от текущего местоположения
]); ?> 
<?= $form->field($model, 'field1')->dropDownList(\yii\helpers\ArrayHelper::map(User::find()->all(), 'id', 'username')); ?> 
<?= Html::submitButton('Пробуем', ['class' => 'btn btn-info', 'id'=>'get_users_submit']); ?>
<?php ActiveForm::end(); ?>
<div id="rendered_user"></div>


Контроллер
public function actionYouraction()
    {
        $request = Yii::$app->request;
        if($request->isAjax){ 
            Yii::$app->response->format = Response::FORMAT_JSON; //Если запрос аяксовый,то отвечаем JSON-ом
            //Тут разбираете полученный запрос, пишете нужную логику, подтягиваете модель пользователя
           
           return ['content'=>$this->renderAjax('_userdata', [ 'model' => $model])];   //Возвращаем JSON-массив в виде вьюшки, которой передаем модель пользователя или любые другие нужные данные
        }   
    }


JS
$(document).on('click' , '#get_users_submit' , function(e) {
    e.preventDefault();
    var target= $('#rendered_user'), //В этот блок выводим полученные данные 
          form = $('#get_users'), //Выбираем нашу форму
          url = form.attr('action'), //Узнаем url для отправки
          data =  form.serializeArray(); //Сериализуем форму
    $.ajax({
            url: url,
            method: 'POST',
            data: data,
            error: function (response) {
                //Если ошибка запроса, то что-то делаем
            },
            success: function (response) {
                //Если запрос прошел, то что-то делаем
               //Контроллер вернет данные в переменную response, разберите её, выведите что нужно
               console.log(response);
               target.html(response.content);
            },
        });

});


Всё по памяти, код не проверял.
Суть вроде должна быть ясна.
Ответ написан
@parazitl2 Автор вопроса
Решил проблему как написал Станислав Казанин.

Выпадающий список, при выборе пункта из которого будет обновляться поле на странице с данными пользователя (id списка например "useridfield") :
<?php echo $form->field($model, 'user_id')->widget(Select2::classname(), [        
        'data' => ArrayHelper::map(User::find()->all(), 'id', 'username'),
        'language' => 'ru',
        'options' => ['placeholder' => 'Выберите пользователя ...', 'id' => 'useridfield', 'value' => Yii::$app->user->identity->getId(),],
        'pluginOptions' => [
            'allowClear' => true
        ],
    ])->label('Автор заявки'); ?>

Сам блок на этой же странице, в котором обновляются данные пользователя (id поля, например, "newtry"):

<div id="newtry">
        <?= $this->render('/user/_userdataview', [
            'model' => Yii::$app->user->identity,
        ]); ?>
</div>

А это скрипт (решил пока оставить его внизу страницы, потом можно вынести в отдельный файл), который выполняет всю данную работу:

<?php 
$script = <<< JS
   
$('#useridfield').change(function(){
    $.ajax({
        type: "GET",
        url: "/basic_yii/web/user/showuserdata?user_id="+$(this).val(),
        success: function(data) {
            $("#newtry").html(data)
        }
    })
});
        
JS;
$this->registerJs($script);
?>

В скрипте $('#useridfield') - это id поля формы с выпадающим списком (указано в массиве options), $("#newtry") - это id специально отгороженного тегами div поля, которое полностью обновляется при клике на выпадающий список, а по адресу /basic_yii/web/user/showuserdata?user_id= лежит экшен контроллера:

public function actionShowuserdata($user_id)
    {
        $model = \app\models\User::findIdentity($user_id);
               
        return $this->renderPartial('_userdataview', [
            'model' => $model,
        ]);
    }


Надеюсь, это кому-нибудь пригодится =)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы