Валидация динамически добавлемых полей в Yii

от автора

Все началось с новой работы, на которой пришлось отказать от Zend и перейти на Yii. При создании личного кабинета для сайта потребовались динамическое добавление полей в форме. После ковыряния в интернете пришло такое решение. Поехали:

Проблем было 2. Первое это организовать форму в несколько шагов — с этим помог справиться wizard-behavior (http://www.yiiframework.com/extension/wizard-behavior). Немного переделав, сделал на один action и одну модель. Валидация полей происходит на основе сценариев.
Добавление динамических полей сделал через ajax через render-partial вьюшки, которая содержала необходимые поля.

Форма создается во view:

$form=$this->beginWidget('CActiveForm', array(                     'id'=>'create_order_step1',                     'enableClientValidation'=>true,                     'clientOptions'=>array(                         'validateOnSubmit'=>true,                         'validateOnType' => true,                     ),));  

В ней же выводим кнопку для добавление полей:

echo CHtml::button('добавить место', array('class' => 'place-add btn')); <script> $(".place-add").click(function(){     var index = $(".new-place").size()+1;       /// считаем  кол-во уже добавленных блоков с полями.      $.ajax({         success: function(html){             $("#add_place").append(html);      // выводим во вью наши поля.         },         type: 'get',         url: '/index.php/site/field',      // делаем ajax зарос к action         data: {             index: index         },         cache: false,         dataType: 'html'     }); }); </script> 

Action:

public function actionField($index = false)     {         $model = new CreateOrderForm();         $this->renderPartial('_add_place_fields', array(             'model' => $model,             'index' => $index,         ));     } 

Получаем номер блока, который уже есть +1.

Динамические поля:

<table class="new-place" id="place_n<?php echo$index; ?>">                                            <tr>             <td>                 <?php                 echo CHtml::activeTextField($model, "place_weight[$index]");       /// создаем поля с индексами.                 echo CHtml::error($model, "place_weight[$index]");               // вываливаем ошибки валидации                  ?>             </td>         </tr> </table> 

В основном action валидацию делаем просто $model->validate(scenario) // сценарий менялся в зависимости от шага.
Если валидация не прошла тогда смотрим кол-во полей в модели и отдаем во вью. (Чтобы при ошибки валидации динамически добавленные поля не исчезли)

if(isset($model->attributes['place_weight'])){         $count = count($model->attributes['place_weight']); } $this->render('view', compact('model', 'count'); 

Во вью для этого выводим эти поля так:

for($i =1; $i<$count; $i++){      $this->renderPartial('_add_place_fields', array(               'model' => $model,               'index' => $i,      )); } 

Ну и самое главное — Модель и валидация:

public function rules()     {         return array(array('place_weight', 'validatePlace', 'on'=>'step1'), );     } public function validatePlace($attribute,$params)       //здесь волшебная функция которая валидует массив динамически добавляемых полей.     {         foreach($this->place_weight as $key_w => $weight){             if (empty($weight)) {                 $this->addError('place_weight['.$key_w.']', 'Поле должно быть заполнено');                 break;             }         } } 

Собственно все. Думаю начинающим в yii, вроде меня это сократит много времени.

ссылка на оригинал статьи http://habrahabr.ru/post/181642/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *