yii2yii2-validation

Yii2 form validation - compare password repeat only when password field is filled


My form validation uses the following rules:

[['password', 'password_repeat'], 'required'],
['password_repeat', 'compare', 'compareAttribute' => 'password', 'message' => "Passwords don't match"],

How to write rules for password_repeat to compare it with password only if user fill password field. If user skip password, validation for password_repeat should be also skipped.


Solution

  • You can use scenarios for that:

    public function rules() {
        return [
            [['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
            [['username', 'password', 'password_repeat'], 'required', 'on' => self::SCENARIO_REGISTER],
            [
                'password_repeat', 'compare', 'compareAttribute' => 'password',
                'message' => "Passwords don't match", 'on' => self::SCENARIO_REGISTER,
            ],
        ];
    }
    

    This allows you to set different rules for different forms (different fields required on login and registration).

    You may also consider creating different models for different forms with own rules(), like LoginForm and RegisterForm. This is actually more clean solution and gives more control.


    EDIT

    For conditional rules you should use when property:

    public function rules() {
        return [
            [['password', 'password_repeat'], 'string'],
            [
                'password_repeat', 'compare', 'compareAttribute' => 'password',
                'message' => "Passwords don't match", 'skipOnEmpty' => false,
                'when' => function ($model) {
                    return $model->password !== null && $model->password !== '';
                },
            ],
        ];
    }