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