yii2-cookbook icon indicating copy to clipboard operation
yii2-cookbook copied to clipboard

Suggestion: determine whether validation was successful in js activeform "afterValidate" event

Open vercotux opened this issue 7 years ago • 5 comments

Seems like a very trivial, common requirement, but there doesn't seem to be any simple way to know whether validation was successful inside the afterValidate client event. How do we do it?

This would fit perfectly into the Forms activeform js chapter.

vercotux avatar Mar 28 '17 03:03 vercotux

Can't you check length of errorAttributes?

function (event, messages, errorAttributes) {
    if (errorAttributes.length) {
        // not valid
    } else {
       // valid
    }
}

samdark avatar Mar 29 '17 00:03 samdark

That was what I initially tried, but it does not work, because errorAttributes does not contain all validation errors, so you will get false positives. It only contains validation errors of fields rendered by ActiveForm! Meaning if you used something like

<?= Html::activeHiddenInput($model, 'test'); ?>

then test would not be part of errorAttributes even when it has validation errors!

Now, this would all sort of make sense, if we were dealing purely with client-side validation. After all, client-side does not know if there are any validation errors on the server-side... until you introduce AJAX validation! :)

With AJAX validation, we do know if there were server-side validation errors, so we should be able to know if validation was successful in the afterValidate event. But how? We cannot rely on errorAttributes because it does not contain server-side validation errors even when using AJAX validation. Maybe this is a bug?

vercotux avatar Mar 29 '17 02:03 vercotux

According to code it should be available in AJAX validation as well. Please create a ticket in the main Yii 2.0 repo with a clear way to reproduce the issue. Thanks.

samdark avatar Mar 29 '17 11:03 samdark

Alright. In the meantime I have found a working solution. Turns out that messages inside afterValidate will always contain error messages (including those coming from AJAX validation!), no matter how we rendered our ActiveForm. We can use this function to reliably determine whether validation was successful:

function isValid(messages) {
    for (var i in messages) {
        if (messages[i].length>0) {
            return false;
        }
    }
    return true;
}

Usage example:

function (event, messages, errorAttributes) {
    if (isValid(messages)) {
        // valid
    } else {
       // not valid
    }
}

vercotux avatar Mar 30 '17 07:03 vercotux

Great. Would you like to make a pull request adding it to recipe?

samdark avatar Mar 30 '17 14:03 samdark