it-swarm.com.de

Yii2: Wie kann ich die benutzerdefinierte Validierungsfunktion für aktive Form verwenden?

Im Modell meines Formulars habe ich eine benutzerdefinierte Validierungsfunktion für ein auf diese Weise definiertes Feld

class SignupForm extends Model
{
    public function rules()
    {
        return [
            ['birth_date', 'checkDateFormat'],

            // other rules
        ];
    }

    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

Die Fehlermeldung wird nicht unter dem Feld in der Formularansicht angezeigt, wenn ich auf die Schaltfläche zum Senden drücke, während andere Regeln wie die erforderliche E-Mail-Adresse und das Kennwort angezeigt werden.

Ich arbeite an dem ursprünglichen Anmeldeformular. Um sicher zu gehen, dass es sich nicht um ein eingereichtes Problem handelt, habe ich die Regel festgelegt

['username', 'checkDateFormat']

und entfernte alle anderen Regeln, die sich auf das Benutzername-Feld beziehen, aber die Nachricht erscheint auch nicht dafür.

Ich habe versucht, nichts als Parameter an checkDateFormat zu übergeben. Ich habe versucht, den Namen des Feldes explizit an addError() zu übergeben.

$this->addError('username', '....');

aber nichts erscheint.

Auf welche Weise können Sie eine benutzerdefinierte Validierungsfunktion festlegen? 

20
Alhazred

Hast du die Dokumentation gelesen?

Gemäß den obigen Validierungsschritten lautet das Attribut wenn und nur dann validiert, wenn es sich um ein in .__ deklariertes aktives Attribut handelt. Szenarien () und ist mit einer oder mehreren aktiven Regeln verknüpft in Regeln () deklariert.

Ihr Code sollte also so aussehen:

class SignupForm extends Model
{
    public function rules()
    {
        return [
            ['birth_date', 'checkDateFormat'],

            // other rules
        ];
    }

    public function scenarios()
    {
        $scenarios = [
            'some_scenario' => ['birth_date'],
        ];

        return array_merge(parent::scenarios(), $scenarios);
    }

    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

Und im Controller-Set-Beispiel, Beispiel:

$signupForm = new SignupForm(['scenario' => 'some_scenario']);
10
TomaszKane

Versuchen Sie, die Überprüfung auf ein leeres Feld zu erzwingen

['birth_date', 'checkDateFormat', 'skipOnEmpty' => false, 'skipOnError' => false],

Stellen Sie außerdem sicher, dass Sie Ihrem birth_date-Feld in Ihrer Ansicht keine ID zuweisen. 

Wenn Sie eine ID für Ihren birth_date haben, müssen Sie die selectors angeben.

<?= $form->field($model, 'birth_date', ['selectors' => ['input' => '#myBirthDate']])->textInput(['id' => 'myBirthDate']) ?>
5
Michael Nguyen

Sie müssen $model->validate() irgendwo auslösen, wenn Sie die Klasse Model erweitern.

5
Josue Mota

Um benutzerdefinierte Überprüfungen in yii 2 vorzunehmen, können Sie eine benutzerdefinierte Funktion in model schreiben und diese Funktion in der Regel ..__ zuweisen, z. Ich muss Passwortkriterien in password anwenden, dann schreibe ich so in model.

public function rules()
{
    return [
        ['new_password','passwordCriteria'],
    ];
}

public function passwordCriteria()
{
    if(!empty($this->new_password)){
        if(strlen($this->new_password)<8){
            $this->addError('new_password','Password must contains eight letters one digit and one character.');
        }
        else{
            if(!preg_match('/[0-9]/',$this->new_password)){
                $this->addError('new_password','Password must contain one digit.');
            }
            if(!preg_match('/[a-zA-Z]/', $this->new_password)){
                $this->addError('new_password','Password must contain one character.');
            }
        }
    }
}

Referenzen: - Formularvalidierung in yii 2

5

Bei der Verwendung des CRUD-Generators bin ich darauf gestoßen. Die generierte actionCreate () - Funktion enthält keinen Modellvalidierungsaufruf, so dass benutzerdefinierte Validatoren nie aufgerufen werden. Das _form enthält auch keine Fehlerzusammenfassung.

Fügen Sie dem _form die Fehlerzusammenfassung hinzu.

<?= $form->errorSummary($model); ?>

... und fügen Sie den Validierungsaufruf - $ model-> validate () - zur Controller-Aktion hinzu

public function actionCreate()
{
    $model = new YourModel();

    if ($model->load(Yii::$app->request->post()) && $model->validate()) {...
2
Steven McElveen

Sie müssen das Modell vom Controller rendern. Ohne das Modell in der Ansicht zu initialisieren. Und im Controller müssen Sie die Validate-Funktion aufrufen

1
Betson

Obwohl es ein alter Beitrag ist, dachte ich, ich sollte antworten. 

Sie sollten eine benutzerdefinierte Validator-Klasse erstellen. Um einen Validator zu erstellen, der die clientseitige Validierung unterstützt, sollten Sie die yii\validators\Validator::clientValidateAttribute()-Methode implementieren, die einen Teil des JavaScript-Codes zurückgibt, der die Validierung auf der Clientseite durchführt. Innerhalb des JavaScript-Codes.

Sie können die folgenden vordefinierten Variablen verwenden:

attribute: der Name des zu überprüfenden Attributs.

value: der zu validierende Wert.

messages: ein Array, in dem die Überprüfungsfehlermeldungen für .__ gespeichert werden. das Attribut.

deferred: ein Array, in das verzögerte Objekte in .__ verschoben werden können. (Im nächsten Abschnitt erklärt).

Das bedeutet, dass Sie messages array verwenden können, um Ihre Nachrichten zur Laufzeit innerhalb des JavaScript-Codeblocks dieser Methode an das Client-Ende zu senden.

Ich werde eine Klasse erstellen, die Dummy-Prüfungen enthält, die so ersetzt werden könnten, wie Sie es möchten. und ändern Sie die Variable namespace entsprechend Ihrer yii2 advanced oder basic.

Custom Client-side Validator

namespace common\components;
use yii\validators\Validator;

class DateFormatValidator extends Validator{
public function init() {
        parent::init ();
        $this->message = 'You entered an invalid date format.';
    }

    public function validateAttribute( $model , $attribute ) {

        if ( /*SOME CONDITION TO CHECK*/) {
            $model->addError ( $attribute , $this->message );
        }
    }

    public function clientValidateAttribute( $model , $attribute , $view ) {

        $message = json_encode ( $this->message , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
        return <<<JS
if ($("#DATE-1").val()=="" || $("#DATE-2").val() =="") {
    messages.Push($message);
}
JS;
    }
}

und dann in Ihrem Modell SigupForm die rule hinzufügen

['birth_date', 'common\components\DateFormatValidator'],

Deferred Validation

Sie können sogar ajax-Aufrufe innerhalb der clientValidateAttribute-Funktion hinzufügen und auf der Basis des Ergebnisses dieses ajax-Aufrufs können Sie eine Push-Nachricht an das Client-Ende senden. Sie können jedoch das deferred-Objekt verwenden, das von yii bereitgestellt wird Aufrufe innerhalb dieses Arrays oder explizit das verzögerte Objekt erstellen und seine resolve()-Methode aufrufen.

Default Yii's deferred Object

public function clientValidateAttribute($model, $attribute, $view)
{
    return <<<JS
        deferred.Push($.get("/check", {value: value}).done(function(data) {
            if ('' !== data) {
                messages.Push(data);
            }
        }));
JS;
}

Mehr über Deferred Validation

1

Sind Sie sicher, dass der erste Parameter von addError nicht so sein sollte

$this->addError(**'attribute'**, Yii::t('user', 'You entered an invalid date format.'));
1
Pino Wackers

Ich hatte ein gemeinsames Problem.

In Ihrer Validierungsfunktion:

public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }

$ params erhält keinen Wert. Es ist eigentlich immer gleich Null. Sie müssen Ihren Attributwert in der Funktion überprüfen:

public function checkDateFormat($attribute, $params)
{
    if($this->birth_date == False)
    {
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

so hat es für mich funktioniert.

1
Максим

Wenn Sie keine Szenarien für Ihr Modell verwenden, müssen Sie Ihr Attribut als "sicher" markieren:

    ['birth_date','safe'],
    ['birth_date', 'checkDateFormat'],

Andererseits können Sie dies zur Datumsüberprüfung verwenden:

    ['birth_date','safe'],
    [['birth_date'],'date', 'format'=>'php:Y-m-d'],

Sie können das Format beliebig ändern. 

0
hesselek