2016-04-25 8 views
0

In meinem Formular aktualisiere ich mehrere Start- und Enddaten vom selben Modell gleichzeitig. Siehe die vereinfachte Form:Yii2: So validieren Sie ein Formular mit mehreren Instanzen desselben Modells

<?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(); ?> 

Im Modell ich steuern müssen, wenn das Enddatum nach dem Startdatum ist:

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

Ich habe versucht, Wähler in ähnlicher Weise zu ändern, wie beschrieben in: Yii2: Validation in form with two instances of same model, aber Ich war nicht erfolgreich. Ich glaube, ich brauche die 'compareAttribute' von 'MyModel-Start' auf 'mymodel- -start' in der Validierung JS zu ändern:

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

, Ich suche nach etwas wie Also:

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

Lösung

die Lösung wird auf die Antwort von lucas basiert.

Im Modell überschreiben ich die Formularname() -Methode, so dass für jedes Datum, das ich eine einzigartige Form Name (für die bestehenden Termine und basierend auf Zufallszahl für neue Termine basierend auf ID) haben:

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; 
} 

Das Formular sieht dann folgendermaßen aus:

<?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(); ?> 

Antwort

1

Überschreiben Sie die FormName() -Methode in Ihrer Modellklasse, um es eindeutig zu machen. Wenn Sie Ihre Modellklasse nicht ändern möchten, erstellen Sie eine Unterklasse, um mit dieser Controller-Aktion zu arbeiten. Danach werden die Felder HTML-ID und Name automatisch eindeutig.