在yii2中验证parent_id

时间:2016-08-05 13:25:20

标签: php forms validation yii2 yii2-advanced-app

您好我在验证方面有问题,我正在使用yii2高级应用程序。

我在创建菜单时有一个parent_id我给菜单名称并提供天气这个菜单是否是父菜单,如果选中了父菜单复选框,如果没有,则会从下拉菜单中选择。

问题是如果在规则下的模型中根据需要创建此父ID,则在视图中,复选框和下拉列表都将验证,并且两者都将显示必需。但我只想要其中任何一个。如果我没有按要求提供,那么验证本身就不会发生。见下图。
In this both check-box and drop-down is required.

这是我的活动表格..

   <?= $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>

如果两个问题都留空,我希望验证能够实现。请告诉我任何解决方案。

2 个答案:

答案 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();
        }"],
    ];
}
  • 请注意,我确实希望您的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);
}

答案 1 :(得分:0)

我认为您必须为此目的使用自定义验证:

public function rules()
    {
        return [
            ['field1', function ($attribute, $params) {
                    // if (...) 
                    $this->addError($attribute, 'Must field1 or field2 be set');
                }
            }],
        ];
    }