Yii2 DynamicForm: Демо 3: Вложенная динамическая форма с типами комнат

Возможно ли иметь разные типы комнат в "демонстрации 3: Вложенная динамическая форма "и разделить комнаты по типам? Например, если я хочу создать то же, что и в демо 3, и добавить тип для каждой комнаты. Я хочу иметь номера типа A, номера типа B и номера типа C. Возможно ли это? (типы предварительно загружены в базу данных, пользователю не нужно вставлять новый тип или выбирать один тип. Если я хочу вставить «тип комнаты A», я просто добавляю его туда, где он принадлежит)

Я изменил html, но в массиве комнат в контроллере не было всех комнат (потому что первые были перезаписаны). Итак, что мне нужно сделать, чтобы все работало нормально?

На картинке вы можете увидеть подход, я хочу, чтобы он работал, потому что просто редактирование html не сработало.

подход


person Fernando Torres    schedule 28.03.2017    source источник


Ответы (1)


Хорошо, вот мое решение:

Создайте еще 2 класса, расширенных из «Модели». Итак, у меня есть 3 класса: Room (ActiveRecord), RoomB (Model), RoomC (Model). Так что я могу представить 3 типа комнаты. Атрибутами двух классов «Модель» являются «id» и «описание» класса «ActiveRecord» (помните, мы говорим о комнате). В "_form.php" я добавил еще два "render('_form-rooms')" внутри div с классом "col-md-4", чтобы получить разделение.

<td>
<div class="row">
<div class="col-md-4">
                    <?= $this->render('_form-rooms', [
                        'form' => $form,
                        'indexHouse' => $indexHouse,
                        'modelsRoom' => $modelsRoom[$indexHouse],
                    ]) ?>

<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</div>
<div class="col-md-4">
                    <?= $this->render('_form-rooms', [
                        'form' => $form,
                        'indexHouse' => $indexHouse,
                        'modelsRoom' => $modelsRoomB[$indexHouse],
                    ]) ?>

<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</div>
<div class="col-md-4">
                    <?= $this->render('_form-rooms', [
                        'form' => $form,
                        'indexHouse' => $indexHouse,
                        'modelsRoom' => $modelsRoomC[$indexHouse],
                    ]) ?>

<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</div>
</div>
                </td>

В «actionCreate» я создал 2 дополнительных массива, представляющих 2 класса «Модель», поэтому у меня есть эти 3 массива: $modelsRoom = [[new Room]]; $modelsRoomB = [[новая комнатаB]]; $modelsRoomC = [[новая комнатаC]]; Я специально изменил всю логику кода внутри actionCreate двумя дополнительными массивами, так что, например, в "isset($_POST['Room'][0][0])" я мы также запрашиваем «isset($_POST['RoomB'][0][0])» и «isset($_POST['RoomC'][0][0])»:

// validate person and houses models
           $valid = $modelPerson->validate();
           $valid = Model::validateMultiple($modelsHouse) && $valid;
           $valid2 = $valid3 = $valid;

           if (isset($_POST['Room'][0][0])) {
               foreach ($_POST['Room'] as $indexHouse => $rooms) {
                   foreach ($rooms as $indexRoom => $room) {
                       $data['Room'] = $room;
                       $modelRoom = new Room;
                       $modelRoom->load($data);
                       $modelsRoom[$indexHouse][$indexRoom] = $modelRoom;
                       $valid = $modelRoom->validate();
                   }
               }
           }

           if (isset($_POST['RoomB'][0][0])) {
               foreach ($_POST['RoomB'] as $indexHouse => $rooms) {
                   foreach ($rooms as $indexRoom => $room) {
                       $data['Room'] = $room;
                       $modelRoom = new Room;
                       $modelRoom->load($data);
                       $modelsRoomB[$indexHouse][$indexRoom] = $modelRoom;
                       $valid2 = $modelRoom->validate();
                   }
               }
           }


           if (isset($_POST['RoomC'][0][0])) {
               foreach ($_POST['RoomC'] as $indexHouse => $rooms) {
                   foreach ($rooms as $indexRoom => $room) {
                       $data['Room'] = $room;
                       $modelRoom = new Room;
                       $modelRoom->load($data);
                       $modelsRoomC[$indexHouse][$indexRoom] = $modelRoom;
                       $valid3 = $modelRoom->validate();
                   }
               }
           }

поэтому я спрашиваю, верны ли 2 дополнительные «действительные» переменные, чтобы продолжить

if ($valid && $valid2 && $valid3) {
                $transaction = Yii::$app->db->beginTransaction();
                try {
                    if ($flag = $modelPerson->save(false)) {
                        foreach ($modelsHouse as $indexHouse => $modelHouse) {

                            if ($flag === false) {
                                break;
                            }

                            ... (continue with the same code)

и при рендеринге формы я передал в качестве параметра созданные дополнительные массивы:

return $this->render('create', [
            'modelPerson' => $modelPerson,
            'modelsHouse' => (empty($modelsHouse)) ? [new House] : $modelsHouse,
            'modelsRoom' => (empty($modelsRoom)) ? [[new Room]] : $modelsRoom,
            'modelsRoomB' => (empty($modelsRoomB)) ? [[new RoomB]] : $modelsRoomB,
            'modelsRoomC' => (empty($modelsRoomC)) ? [[new RoomC]] : $modelsRoomC,
        ]);

В представлении «_form.php» вы можете увидеть код выше, я использовал два дополнительных массива при рендеринге двух дополнительных «_form-rooms».

В «_form-rooms» я удалил код, представляющий идентификатор модели, потому что в «actionUpdate» я удалил все «Дома», поэтому все их «комнаты» тоже будут удалены. После этого я просто делаю то же самое, что и в «actionCreate» (после поста).

Я надеюсь, что вы можете понять мое решение. Возможно, это не лучшее решение, но оно работает для меня. Есть больше деталей, которые я опустил, чтобы не слишком расширять этот ответ, но вы всегда можете связаться со мной;)

Если вам нужна дополнительная информация, напишите мне.

person Fernando Torres    schedule 31.03.2017