So I need to add an AJAX validation for the field VAT number of shipping and billing address in checkout page, which is basically like this:
define([], function () {
return {
validate:function (value){
$.ajax({
url: 'path/to/the/validation/controller',
type: 'get',
dataType: 'json',
cache: false
}).done(function (response) {
return response;
}).fail(function () {
return false;
});
return false;
}
};
});
But as you can see, this validation won't work because AJAX async is involved, so it will always return false regardless the validation result.
I want to avoid async: false
because it causes bad user experience as it freeze the page while validating, so I come up with these work around, but none works:
1. I create a custom error message span below the VAT field, and set the message myself in AJAX callback:
define([], function () {
return {
validate:function (value){
$.ajax({
url: 'path/to/the/validation/controller',
type: 'get',
dataType: 'json',
cache: false
}).done(function (response) {
if (response) {
$('.vat-error-message span').html('');
window.vatValidation = true; // When submit form, I check this value to accept or rejecting the form submit.
} else {
$('.vat-error-message span').html($t('Invalid VAT Number'));
window.vatValidation = false;
}
}).fail(function () {
$('.vat-error-message span').html($t('Invalid VAT Number'));
window.vatValidation = false;
});
return true;
}
};
});
Problem: many other events that validating the form such as saving new shipping or billing address still expecting return result from the validator, which is always true regardless the validation result.
2. I found a validation method named
remote
where you basically add it intodata-validate
which is pretty good: (more information here: Magento 2 - jQuery validation remote method)
<input name="vat_id" data-validate="{'remote':'path/to/the/validation/controller'}"/>
Problem: It only works outside checkout page, e.g edit address in account page. Seem like in checkout page, they use a whole different set of validation rule which isn't included remote
.
My only hope now is trying to get remote
works in checkout page by calling it in my custom validation rule like this:
$.validation.methods['remote'].call();
However, it's just an idea and I haven't found a way to get it works.
$.validation.methods['remote'].call();
, it throw error, saying that "this.option() is not a function" no matter which param I pass into it.window.vatValidation
to store the validation result. After that, you'll need to manually disabling form submitting ifwindow.vatValidation
is false, and also manually setting the validation error message. I can write an answer for you if you want detailed approach, but it'll take time. Tell me if you need it.async:false
if you don't mind having your browser freeze while your validator is doing its work.