Yii2:在具有两个相同模型实例的表单中进行验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Yii2:在具有两个相同模型实例的表单中进行验证相关的知识,希望对你有一定的参考价值。

我有一个型号Booking,其字段为shipping_address和billing_address,两者都是型号地址。我现在想要将它们打印到基本上运行良好的相同形式,问题是两个模型的字段具有相同的ID。例如,shipping_address中的字段“zip”具有id“zip”,billing_address中的“zip”也具有“zip”作为其id。

如果我现在填写表单,它会同时验证两个字段,而其中只有一个字段实际为真。

我已经将字段的名称更改为Shippping_Address ['zip']和Billing_Address ['zip'],因此控制器能够识别两种模型。

以下是字段的打印方式:

<?= $form->field($billing_address, 'address_line_1')->textInput(['maxlength' => 45, 'name'=> 'Billing_Address[address_line1]']); ?>
<?= $form->field($billing_address, 'address_line_2')->textInput(['maxlength' => 45, 'name'=> 'Billing_Address[address_line2]']) ?>
<?= $form->field($billing_address, 'zip')->textInput(['maxlength' => 11, 'name'=> 'Billing_Address[zip]']) ?>
<?= $form->field($billing_address, 'city')->textInput(['maxlength' => 45, 'name'=> 'Billing_Address[city]']) ?>
<?= $form->field($billing_address, 'country')->textInput(['maxlength' => 45, 'name'=> 'Billing_Address[country]']) ?>

<?= $form->field($shipping_address, 'address_line_1')->textInput(['maxlength' => 45, 'name'=> 'Shipping_Address[address_line1]']); ?>
<?= $form->field($shipping_address, 'address_line_2')->textInput(['maxlength' => 45, 'name'=> 'Shipping_Address[address_line2]']) ?>
<?= $form->field($shipping_address, 'zip')->textInput(['maxlength' => 11, 'name'=> 'Shipping_Address[zip]']) ?>
<?= $form->field($shipping_address, 'city')->textInput(['maxlength' => 45, 'name'=> 'Shipping_Address[city]']) ?>
<?= $form->field($shipping_address, 'country')->textInput(['maxlength' => 45, 'name'=> 'Shipping_Address[country]']) ?>

编辑:执行tony的答案后:

<?= $form->field(
            $shipping_address,
            'address_line_1',
            [
                'selectors' => [
                    'input' => '#shipping-address_line_1',
                    'container' => '.shipping-address_line_1'
                ],
                'options' =>
                    ['class' => 'shipping-address_line_1']
            ])->textInput([
                'maxlength' => 45,
                'name'=> 'Shipping_Address[address_line1]',
                'id'=>'shipping-address_line_1',
            ]); ?>

我也更改了容器类,因为它与另一个字段的容器类相同。现在第二个字段(代码如上所示)运行正常。问题是,第一个字段(代码未更改)不再进行验证。

怎么能解决这个问题?

答案

因为您使用一个模型类在一个页面上生成两组输入,所以yii2为它们生成相同的clientValidation规则。要分离验证,您需要为每个需要手动验证每个集合的输入设置id属性。对于您的zip输入字段,解决方案将是下一个(根据最新评论编辑):

//Billing
$form->field($billing_address, 'zip', 
[
    'selectors' => [
        'input' => '#billing-zip',
        'container' => '#billing-container',
    ],
    'options' => ['id' => 'billing-container'],
])->textInput(['maxlength' => 11, 
               'name'=> 'Billing_Address[zip]', 
               'id'=>'billing-zip']); 

//Shipping
$form->field($shipping_address, 'zip', 
[
    'selectors' => [
        'input' => '#shipping-zip',
        'container' => '#shipping-container',
    ],
    'options' => ['id' => 'shipping-container'],
])->textInput(['maxlength' => 11, 
               'name'=> 'Shipping_Address[zip]', 
               'id'=>'shipping-zip']);

如您所见,我们在textInput选项中添加了自定义id属性,并在字段选项中为js验证设置了相应的选择器。 Read about selectors property

以上是关于Yii2:在具有两个相同模型实例的表单中进行验证的主要内容,如果未能解决你的问题,请参考以下文章

Yii2.0自定义验证码

PHP面试题精讲—从Yii2源码ActiveForm看如何安全处理表单验证

PHP面试题精讲—从Yii2源码ActiveForm看如何安全处理表单验证

Yii2.0中rules验证的调试

yii2中添加验证码的实现方法

Yii2 - 表单验证规则:如何使用自定义验证功能或替代?