Подтвердить что ты не робот

Добавление еще нескольких полей в форму в yii2 с помощью ajax

У меня есть Yii2 form:

<?php $form = ActiveForm::begin(['id' => 'que']); ?>
    <?php echo $form->field($model, 'type')
            ->dropDownList($questionTypes, [
                'class' => 'form-control ng-pristine ng-valid ng-touched',
                'prompt' => 'Select question type',
                'ng-model' => 'que.type',
                'ng-change' => 'addAnswerOptions(que);',
        ]);
    ?>
<?php ActiveForm::end(); ?>

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

Как я могу это сделать?

4b9b3361

Ответ 1

Из информации, которую вы даете, вот что я хотел бы предложить.

1) Динамический - нет AJAX

Создайте форму со всеми полями, которые вам нужны, просто добавьте каждый "сценарий" в отдельный div, как показано ниже:

<?php $form = ActiveForm::begin(['id' => 'que']); ?>
    <?php echo $form->field($model, 'type')
            ->dropDownList($questionTypes, [
                'class' => 'form-control ng-pristine ng-valid ng-touched',
                'prompt' => 'Select question type',
                'ng-model' => 'que.type',
                'ng-change' => 'addAnswerOptions(que);',
        ]);
    ?>
    <div class="form-option" data-type="class" style="display:none;">
        <?php
            // ... fields here for case type == class
        ?>
    </div>
    <div class="form-option" data-type="prompt" style="display:none;">
        <?php
            // ... fields here for case type == prompt
        ?>
    </div>
    <div class="form-option" data-type="ng-model" style="display:none;">
        <?php
            // ... fields here for case type == ng-model
        ?>
    </div>
    <div class="form-option" data-type="ng-change" style="display:none;">
        <?php
            // ... fields here for case type == ng-change
        ?>
    </div>
<?php ActiveForm::end(); ?>

Затем вам нужно будет зарегистрировать код Javascript для отображения правильных блоков в зависимости от выбранного варианта выпадающего списка. Ниже приведен пример использования JQuery:

$(document).ready(function(){
    $('select.form-control').change(function(){
        $('.form-option').hide(); // hide all options if an option is showing
        var index = $('select.form-control').index();
        $('div[data-type="'+index+'"]').show(); //show the correct fields
    });
});

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

Как только ваша форма будет отправлена, вам придется обрабатывать каждый случай в своем контроллере. Вы можете использовать простой набор операторов if(), которые проверяют выпадающее значение. Или вы можете установить свою модель сценарий проверки в соответствии с выпадающим значением.

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

2) Использование Ajax

В случае, если вы хотите использовать вызовы ajax для загрузки дополнительных полей формы, вам нужно будет сделать комбинацию controller/action, которая вернет поля в зависимости от типа, который вы передаете в GET

Это действие сгенерирует html полей, которые вы хотите отобразить. Вот пример:

public function actionAjaxFields($type)
{
    $html = '';
    if($type == "class")
    {
        $html .= Html::textInput('Field1');
    }
    elseif($type == "prompt")
    {
        $html .= Html::textInput('Field2');
    }
    else
    {
        // etc...
    }
    return $html;
}

Обратите внимание, что вы также можете передать идентификатор пользователя этому методу, который позволит вам сгенерировать модель и использовать Html::activeTextInput(), однако вы не сможете воспользоваться функциями ActiveForm.

Как только это будет сделано, вы должны привязать функцию к событию изменения выпадающего списка и использовать что-то вдоль строк:

var responsePromise = $http.get("controller/ajax-fields", {params: {type: <type-from-dropdown>}});

К сожалению, я мало знаю о angularjs, так что это объем помощи, которую я могу дать на стороне JavaScript. Я уверен, что более чем достаточно информации о google/stackoverflow о привязке событий и добавлении данных в DOM в angularjs, чтобы вы могли работать.

Сообщите мне, могу ли я оказать какую-либо дополнительную помощь на стороне Yii2.