У меня есть полевой пользовательский код. он будет отключен, если значение listbox является персоналом и включено, если значение списка – admin. В случае с администратором требуется пользовательский режим. но в случае персонала пользовательский запрет отключается, и никакие правила не применяются.
Как это сделать?
Я могу думать о двух путях или их комбинации. Оба требуют некоторой настройки для достижения отличных результатов, но они довольно хороши:
1) Сценарий: обратите внимание, что у меня есть два поля / атрибута: text / dropdown В вашем контроллере:
public function actionScenario() { $model=new ScenarioForm; // if it is ajax validation request if(isset($_POST['ajax']) && $_POST['ajax']==='scenario-form') { if($_POST['ScenarioForm']['dropdown'] == 'admin') $model->scenario = 'admin'; echo CActiveForm::validate($model); Yii::app()->end(); } // collect user input data if(isset($_POST['ScenarioForm'])) { $model->attributes=$_POST['ScenarioForm']; if($model->dropdown == 'admin') $model->scenario = 'admin'; // validate user input $model->validate(); //do other stuff } // display the login form $this->render('scenario', array('model'=>$model)); }
Как вы можете видеть, я проверяю, является ли раскрывающееся значение admin; если это так, я изменяю сценарий модели на «admin». В правилах модели у меня есть следующее:
public function rules() { return array( array('dropdown', 'required'), array('text', 'required', 'on' => 'admin'), ); }
Видите ли, текст нужен только тогда, когда сценарий является администратором. Когда у вас теперь есть администратор в раскрывающемся списке и ничего в текстовом поле, и отправьте форму, вы получите правильные ошибки. Если вам нужна мгновенная обратная связь ajax, когда пользователь меняет раскрывающийся список, вы можете захотеть этого в своем представлении:
<?php echo $form->labelEx($model,'dropdown'); ?> <?php echo $form->dropDownList($model,'dropdown', array('admin' => 'Admin', 'staff' => 'Staff!')); ?> <?php echo $form->error($model,'dropdown', array('afterValidateAttribute' => 'js:function(form, attribute, data, hasError) { mSettings = $.fn.yiiactiveform.getSettings(form); $.fn.yiiactiveform.updateInput(mSettings.attributes[1], data, form) }')); ?>
Третий параметр в раскрывающемся списке ошибок – это массив, который содержит несколько параметров html, таких как обратный вызов, который вызывается после того, как выпадающее меню проверено с помощью ajax. Как правило, обновляется только текущее поле, когда вы выполняете ajax-валидацию (даже если вы получаете все ошибки). Поэтому мы указываем в обратном вызове, что также необходимо обновлять ошибки для текстового поля. Теперь вы увидите, что вы получите сообщение об ошибке при выборе администратора в раскрывающемся списке (а не при запуске).
Это не идеально, так как вы не получаете свой приятный обязательный * для текстового поля, и вы получаете предупреждение немедленно. Я не уверен, что Yiiactiveform имеет функцию для рисования поля, а не предупреждения. Но вы могли бы расширить его, чтобы сделать это, или использовать пользовательские js в обратном вызове. Если вам нужна нормальная проверка после отправки, вы также можете добавить требуемый класс к текстовой метке с помощью настраиваемого Javascript. На данный момент я не уверен, имеет ли CActiveForm специальный атрибут для этого атрибута.
2) правило пользовательской проверки. Подобно одному, хотя вы не используете сценарий (но все же js callback в представлении). Вместо этого вы создаете собственное правило проверки для раскрывающегося списка и помещаете его в массив правил. Когда выпадающее меню изменяется, мы добавляем ошибку в текстовое поле.
public function check_dropdown($attribute,$params){ if($this->$attribute=="admin"){ $this->addError('text', 'Please enter Text!'); $this->clearErrors('text'); } } public function check_text($attribute,$params){ if($this->$attribute!=""){ $this->clearErrors('text'); } }
Здесь вам не нужно устанавливать сценарий в контроллере. Но вы теряете необходимое правило. Здесь же проблема с отсутствующей звездочкой.
Я бы, вероятно, пошел бы в путь 1. Если вы не хотите прямого предупреждения, вам, вероятно, придется прочитать сообщение об ошибке из JSON, проверить, является ли оно правильным, и применить правый класс к метке текста с помощью пользовательский Javascript в функции обратного вызова.