0

I am trying to return true for the entire validator.registercallback function if the following ajax script doesn't return 1. However, it isn't working, and I think its probably something basic that I'm missing, but I can't figure it out.

validator.registerCallback('unique_username', function(value) {

        //use ajax to run the check  
        var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
      if(xmlhttp.responseText != 1) {
          alert('Username Exists');
          return false;
      } else {
          alert('Username Available!');
          return true;
      }
    }
  }
xmlhttp.open("GET","uniqueuser.php?username="+value,true);
xmlhttp.send();

})

What's weird is that the following works, it just doesn't work based on the value of the ajax script:

validator.registerCallback('unique_username', function(value) {

        //use ajax to run the check  
        var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
      if(xmlhttp.responseText != 1) {
          alert('Username Exists');
          return false;
      } else {
          alert('Username Available!');
          return true;
      }
    }
  }
xmlhttp.open("GET","uniqueuser.php?username="+value,true);
xmlhttp.send();

return true;

})

So basically, I can tell it to return true in the main function, but when I try to make it return true ONLY IF the value in the ajax script doesn't return 1, it doesn't work. By the way, the alerts DO WORK. So it IS getting the right value, but it wont return true, or false for that matter.

Any help is appreciated!

Update

validator.registerCallback('unique_username', function(value) {

        //use ajax to run the check  
function ajax_result() {
  var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    }
  }
xmlhttp.open("GET","uniqueuser.php?username="+value,true);
xmlhttp.send();
}

if(ajax_result() != 1) { 

alert('Username Exists');
return false;

} else {

alert('Username Available!');
return true;

}

})
user1751581
  • 87
  • 1
  • 11
  • 2
    Search for "ajax return value" the *asynchronous* bit is of particular importance .. also, consider using a library for AJAX (and no, I don't care which one, but since *you tagged it as jQuery*..) –  Mar 28 '13 at 23:38
  • http://stackoverflow.com/questions/5316697/jquery-return-data-after-ajax-call-success - jQuery, but should show the point (and how to write cleaner code) and if you want *synchronous* behavior (ick!) see http://stackoverflow.com/questions/2942544/synchronous-calls-with-jquery –  Mar 28 '13 at 23:40
  • I tried using the jquery version but it didnt work either – user1751581 Mar 28 '13 at 23:47
  • This is as close as I've gotten, and also, I am still unsure what I should look at – user1751581 Mar 28 '13 at 23:47
  • What if you use validator.registerCallback using a non-anonymous function as second parameter? (you give a function name there instead). That is a function you can call from anywhere then. Which includes the handler where the webpage has been retrieved (in my jQuery solution). – Anders Lindén Mar 29 '13 at 00:34
  • But I have to admit I dont see the point of the callback being called. :) – Anders Lindén Mar 29 '13 at 00:36

3 Answers3

1

What you are missing is that the ajax call is asynchronous. When your function ends, the ajax call has not been completed yet, and the value (true or false) will only be returned later.

To address this, you need to either make the ajax call synchronous or modify your chaining logic, for example reverse it and run validator.registerCallback() inside the ajax call. You could also consider some more sophisticated techniques like promises.

[Update] This is how you make the request synchronous:

xmlhttp.open("GET","uniqueuser.php?username="+value,false);

You'll also need to change the rest of the code, see for example this MDN article.

Christophe
  • 27,383
  • 28
  • 97
  • 140
0

You have added jQuery to the list of keywords to this question so I answer using jQuery:

var username = "foo";
$.get('uniqueuser.php', {username: username}, function(webpage)
{
  if (webpage == 1)
    alert("user exists");
  else
    alert("Username available!");
});
Anders Lindén
  • 6,839
  • 11
  • 56
  • 109
  • `validator.registerCallback('unique_username', function(value) { var username = value; $.get('uniqueuser.php', {username: username}, function(webpage) { if (webpage == 1) { alert("Username Available!"); return true; } else { alert("Username Exists"); return false; } }); })` When I did this I got the alerts right, but its not returning the function true or false – user1751581 Mar 29 '13 at 00:04
  • I want to return true or false for the function `function(value)` within the validator – user1751581 Mar 29 '13 at 00:05
  • Ah, maybe you need to put the code I was writing in a function that takes two parameters, function is_user_existing(username, continuation), continuation is a function object that will be called with the result of the ajax call. Then you use is_user_existing('foo', function(result) { /* do someting */ }); and result is either true or false. – Anders Lindén Mar 29 '13 at 00:08
0

Trying again:

is_user_existing('foo', function(result)
{
  if (result)
    alert("user is existing");
  else
    alert("user is not existing");
});

function is_user_existing(username, continuation)
{
    $.get('uniqueuser.php', {username: username}, function(webpage)
    {
      continuation (webpage == 1);
    });
}
Anders Lindén
  • 6,839
  • 11
  • 56
  • 109