3

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 into data-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.

asked Jul 26, 2019 at 17:32
5
  • Tobe more specific: When I use $.validation.methods['remote'].call();, it throw error, saying that "this.option() is not a function" no matter which param I pass into it. Commented Jul 27, 2019 at 3:46
  • were you able to solve this? I'm stuck too.I tried remote method but couldn't. Commented Sep 6, 2019 at 13:00
  • @shreyasd I couldn't resolve it so I used a work around like mentioned in the question. By using it, we won't care about result returned in the validator, but using window.vatValidation to store the validation result. After that, you'll need to manually disabling form submitting if window.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. Commented Sep 11, 2019 at 4:06
  • @shreyasd Another method is using async:false if you don't mind having your browser freeze while your validator is doing its work. Commented Sep 11, 2019 at 4:07
  • I am having the same issue with another field. The problem with remote seems to be that the template for the components in checkout are .html files whereas the components everywhere else are .phtml so you can't get the correct URL. Ugh every form in this platform is different, and none of them make any sense from a design perspective. Commented Feb 20, 2020 at 8:49

2 Answers 2

2

I know this is an old question, but recently I was in the same situation of adding an ajax based validation on the checkout page to validate the postcode again the selected state using a 3rd party API. To achieve this, I have to add an ajax based validation rule on the checkout page and below is the code snippet I used to achieve this.

define([
'Magento_Ui/js/lib/validation/validator',
'jquery',
'jquery/ui',
'jquery/validate',
'mage/translate'], function(validator,$){
'use strict';
return function() {
 validator.addRule(
 'postcode_state', function (value, element) {
 var isValid = false;
 window.errorMsg = "";
 var data = {}; //Pass the data that you want
 $.ajax({
 url: BACKEND-URL, // you backend url
 data: data,
 type: "POST",
 showLoader: true,
 async: false, //This is required so that it wait for the response
 success: function (response) {
 window.errorMsg = response.error; //setting error message returned from the server
 isValid = response.success; //true or false returned from the server
 }
 });
 return isValid;
 }, function () { //using a callback method to wait for the server response
 return window.errorMsg; //used window.errorMsg, if you want to use any other technique you are good to go
 });
}});

Do let me know in case if you face any issue, will try to resolve your issues.

Thanks

answered Dec 8, 2021 at 6:30
1
  • Thanks. It helps me a lot. Commented Mar 14, 2024 at 10:03
0

You can use the jQuery validation messages for all fields, I think this is the best option. I also applied these.

answered Sep 10, 2022 at 14:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.