我有一个现场客户代码。如果列表框的值为人员,它将被禁用,如果列表框的值为管理员,它将被启用。如果是管理员,则需要客户代码。但在员工的情况下,客户代码被禁用,无需应用任何规则。
怎么做?
我可以想到两种方法,或者是这些方法的组合。两者都需要一些调整以获得完美的结果,但它们都非常好:
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;如果是这样,我将模型的场景更改为“管理员”。在模型规则中,我有这个:
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-validation 时,仅更新当前字段(即使您收到所有错误)。所以我们在回调中指定文本字段的错误也应该更新。您现在会看到,当您在下拉列表中选择 admin 时(不是在启动时)会出现错误。
这并不完美,因为您没有得到文本字段所需的*,并且您会立即收到警告。我不确定 Yiiactiveform 是否具有绘制字段装饰的功能,而不是警告。但是您可能可以扩展它来做到这一点,或者在回调中使用自定义 js。如果只需要提交后正常验证,也可以使用自定义的Javascript在文本标签中添加需要的类。目前我不确定 CActiveForm 的属性中是否有一个特殊参数。
2) 自定义验证规则。和一个类似,虽然你不使用场景(但仍然是视图中的js回调)。相反,您为下拉菜单创建自定义验证规则,并将其放入规则数组中。当下拉列表更改时,我们会在文本字段中添加一个错误。
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。