Yii2:如何验证具有相同模型的多个实例的表单

时间:2016-04-25 14:31:44

标签: yii2 yii2-validation

在我的表单中,我会立即从同一个模型更新更多的开始日期和结束日期。请参阅简化表格:

<?php $form = ActiveForm::begin(); ?>
    <?php foreach($dates as $i=>$date): ?>
        <?= $form->field($date,"[$i]start"); ?>
        <?= $form->field($date,"[$i]end"); ?>
    <?php endforeach; ?>
</table>
<?= Html::submitButton('Save'); ?>
<?php ActiveForm::end(); ?>

在我需要控制的模型中,如果结束日期在开始日期之后:

public function rules() {
    return [
        [['end'], 'compare', 'compareAttribute' =>  'start', 'operator' => '>', 'message' => '{attribute} have to be after {compareValue}.‌'],
    ];
}

我尝试按照Yii2: Validation in form with two instances of same model中的描述更改选择器,但我没有成功。我想我需要改变比较属性&#39;来自&#39; mymodel-start&#39;到了#mymodel- 0 -start&#39;在验证JS中:

{yii.validation.compare(value, messages, {"operator":">","type":"string","compareAttribute":"mymodel-start","skipOnEmpty":1,"message":"End have to be after start.‌"});}

所以,我寻找类似的东西:

$form->field($date,"[$i]end", [
    'selectors' => [
        'compareAttribute' => 'mymodel-'.$i.'-start'
    ]
])

解决方案

解决方案基于 lucas 的答案。

在模型中,我覆盖了formName()方法,因此对于每个日期,我都有一个唯一的表单名称(基于现有日期的ID并基于新日期的随机数):

use ReflectionClass;
...

public $randomNumber;

public function formName()
{
    $this->randomNumber = $this->randomNumber ? $this->randomNumber : rand();
    $number = $this->id ? $this->id : '0' . $this->randomNumber;
    $reflector = new ReflectionClass($this);
    return $reflector->getShortName() . '-' . $number;
}

然后表格如下:

<?php $form = ActiveForm::begin(); ?>
    <?php foreach($dates as $date): ?>
        <?= $form->field($date,"start"); ?>
        <?= $form->field($date,"end"); ?>
    <?php endforeach; ?>
</table>
<?= Html::submitButton('Save'); ?>
<?php ActiveForm::end(); ?>

1 个答案:

答案 0 :(得分:1)

覆盖模型类中的formName()方法,使其唯一。如果您不想更改模型类,请创建它的子类,以便为此控制器操作起作用。执行此操作后,html ID和名称字段将自动唯一。