0

I have been dealing with these issue for a few days, and I can't seem to be able to fix it on my own. I've already asked a question here on Stack regarding this, however I've been told this is resolved by using callback functions. I've done exactly that but the variable inside the callback still isn't changed.

I am using abide validation that is built into the Foundation framework, and I am trying to have my own custom validator for checking if an email already exists in our database. Everything works, even the console.log returns the correct results, but the variable value is not changed from false to true. Only check the code from emailVerification downwards.

Thank you for your help.

$(document).foundation({
  abide : {
    live_validate : false, // validate the form as you go
    validate_on_blur : false,
    patterns: {
       positive_price: /^\+?[0-9]*\,?[1-9]+$/,
     },
     validators: {
         positiveNumber: function(el, required, parent) {
          var value  = el.value.replace(/,/, '.'),
              valid = (value > 0);
          return valid;
        },
        emailVerification: function (el, required, parent) {
          var email = el.value,
          ajax = 1,
          valid = false;

          function checkServer(callback) {
            $.ajax({
                  type: "GET",
                  url: "/check.do?action=userEmailAvailable",
                  data: "userEmail1=" + email + "&ajax=" + ajax,
                  success: callback
            });
          }

          checkServer(function(data) {
            if (data.result == 1) {
                console.log(data.result + "does not exist");
                valid = true;
              } else {
                console.log(data.result + "already exist");
                valid = false;
              }
          });

          return valid;

        }

       }
     }
});
Rayon
  • 36,219
  • 4
  • 49
  • 76
Svedr
  • 589
  • 2
  • 6
  • 21
  • Value of `valid` is initialized as `false` which is being returned as your script will not wait to return valued after `http request` hence you wil be getting `false` in all the situations. You need to use [`promise`](https://www.w3.org/2001/tag/doc/promises-guide) in such cases. – Rayon Sep 29 '15 at 07:36
  • @RayonDabre hmm I was told I could do this with either deffer, callback or promises. So Promise is the only way? – Svedr Sep 29 '15 at 07:41
  • Just check with the library you are using whether they have any approach for remote validation ? – Rayon Sep 29 '15 at 07:42

3 Answers3

1

the valid that you declare in positiveNumber function is locally scoped to that function only. the next time you attempt to access it outside the function you actually create a global var called valid

Dale Corns
  • 225
  • 1
  • 6
  • Hey, I actually define another valid in emailVerification. As I've said, only code from emailVerification downwards is relevant. Thank you anyway for your contribution. – Svedr Sep 29 '15 at 07:40
  • right, but being as how it has no var key word all the other functions that reference valid without var are accessing the same global valid. – Dale Corns Sep 29 '15 at 07:50
1

$.ajax runs asynchronously. You function returns "valid" before callback function is called. You can try running your ajax request synchronously or you need to add logic in your callback function that updates "valid" when it's called
How to create sync ajax
Add validation function to you callback

checkServer(function(data) {
        if (data.result == 1) {
            console.log(data.result + "does not exist");
            valid = true;
          } else {
            console.log(data.result + "already exist");
            valid = false;
          }
        DoCoolValidation(valid)
      });


If you are sure that your server validation is fast enough you can do

    function Validate(dataToSend) {
return JSON.parse($.ajax({
    url: '/check.do?action=userEmailAvailable',
    type: "GET",
    dataType: "json",
    data: dataToSend,
    async: false
}).responseText);}

And use it:

valid = Validate("userEmail1=" + email + "&ajax=" + ajax);

Have a look at this post. It can help

Community
  • 1
  • 1
Lokki
  • 372
  • 1
  • 6
  • 20
1

As many answered, you need async validation and Abide does not support this.

I would suggest you use the excellent Parsley.js library which supports async validators through its Remote plugin

  • So I cannot do this with any of the proposed solutions? I have to change a loot of pages if i now decide to swap abide with parsley, although it does look promising. – Svedr Sep 29 '15 at 08:10
  • Well, everyone is right on the async nature of your problem but none of the proposed "solutions" are going to help you hack Abide to make it work. – Julien Cabanès Sep 29 '15 at 10:11
  • I don't think you should change a lot of pages since Abide and Parsley both works with regular HTML5 form validation like `required` and `pattern` attributes – Julien Cabanès Sep 29 '15 at 10:20