您好我在验证方面有问题,我正在使用yii2高级应用程序。
我在创建菜单时有一个parent_id我给菜单名称并提供天气这个菜单是否是父菜单,如果选中了父菜单复选框,如果没有,则会从下拉菜单中选择。
问题是如果在规则下的模型中根据需要创建此父ID,则在视图中,复选框和下拉列表都将验证,并且两者都将显示必需。但我只想要其中任何一个。如果我没有按要求提供,那么验证本身就不会发生。见下图。
这是我的活动表格..
<?= $form->field($model, 'parent_id')->checkbox(array(
'id'=>'new',
'value'=>'0',
'labelOptions'=>array('style'=>'padding:5px;'),
'disabled'=>false
)); ?>
<div class="select" id="select">
<?= $form->field($model,'parent_id')->widget(Select2::classname(), [
'data' => $menu,
'options' => ['placeholder' => 'Select a Menu name ...'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
</div>
如果两个问题都留空,我希望验证能够实现。请告诉我任何解决方案。
答案 0 :(得分:1)
首先,如果我正确理解您的要求,我会建议您为模型类引入新的虚拟属性,而不是为同一属性分配不同值的2个字段,以获得更清晰的代码:
$form->field($model,'is_parent')->checkbox(...) // don't do 'value'=>'0' here. it will be auto mapped to model virtual attribute.
$form->field($model,'parent_id')->widget(...)
/*
instead of :
$form->field($model,'parent_id')->checkbox(...) // parent_id is 1 or 0 here
$form->field($model,'parent_id')->widget(...)
*/
然后使用Conditional Validation属性将when应用于模型规则中:
public $is_parent;
public function rules()
{
return [
['is_parent', 'boolean'],
// 'parent_id' is required only if the checkbox is not checked
['parent_id', 'required', 'when' => function($model) {
return !$model->is_parent;
}],
];
}
注意:链接的文档也说:
如果您还需要支持客户端条件验证,那么 应该配置带有字符串的whenClient属性 表示返回值确定的JavaScript函数 是否适用该规则。
预期客户端验证脚本基于您的初始规则。所以你有2个选择。您可以在ActiveForm中完全禁用它并使用Ajax验证:
<?php $form = ActiveForm::begin([
...
'enableClientValidation' => false,
'enableAjaxValidation' => true
]); ?>
或者其他选项是将缺少的客户端相关脚本添加到您的规则中,如文档中所示,在您的情况下可能如下所示:
public function rules()
{
return [
['is_parent', 'boolean'],
['parent_id', 'required', 'when' => function($model) {
return !$model->is_parent;
}, 'whenClient' => "function (attribute, value) {
return !$('#menu-is_parent').val();
}"],
];
}
'menu'
。默认情况下,它返回模型类名称。您还可以使用浏览器的开发工具检查复选框输入,并查看Yii为其指定的id
。 最后,如果选中此复选框后应设置特定的parent_id
值,您可以使用beforeSave()或afterValidate()手动将其设置为您需要的任何值,例如:
public function beforeSave($insert)
{
if ($this->is_parent) $this->parent_id = $someModel->id;
return parent::beforeSave($insert);
}
答案 1 :(得分:0)
我认为您必须为此目的使用自定义验证:
public function rules()
{
return [
['field1', function ($attribute, $params) {
// if (...)
$this->addError($attribute, 'Must field1 or field2 be set');
}
}],
];
}