首先,如果我确实正确理解了您的要求,为了获得更简洁的代码,我建议向您的 model 类引入一个新的虚拟属性,而不是为同一属性分配不同值的 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(...)
*/
然后使用when 属性将Conditional Validation 应用到您的模型 规则中:
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();
}"],
];
}
- 请注意,我确实希望您的 formName() 返回
'menu'。默认情况下,它返回模型类名称。您还可以使用浏览器的开发工具检查复选框输入,并查看 Yii 分配给它的 id 是什么。
最后,如果在选中复选框时应设置特定的 parent_id 值,您可以使用 beforeSave() 或 afterValidate() 手动将其设置为您需要的任何值,例如:
public function beforeSave($insert)
{
if ($this->is_parent) $this->parent_id = $someModel->id;
return parent::beforeSave($insert);
}