0

(please don't mark it as a duplicate before you read it through thanks ^_^) I would like to implement a user registration form. Before the user clicks "submit", it calls a function check_username() which checks whether the username is available. If the function returns true, the form will be submitted otherwise not. The form is like this:

<form action="register/sumbit" method="post" onsubmit="return check_username()">
...
</form>

To implement the check_username function, I adopted the method proposed in How to return the response from an AJAX call? , but it did not work for me. Maybe I misunderstood it. Here is my function:

function check_username()
{
  return $.post(url, {data}); //post the input username to sever to see whether it exists. I omitted something for simplicity here
}
check_username().done(
        function(data){
            if(data=="true")//username doesn't exist 
                return true;
            else if(data=="false") 
                            return false;       
            }).fail(function(){});

Basically, I want check_username to return a boolean value, and the value (true or false) will determine whether the form is going to be submitted or not. The result is that "check_username.done()" is implemented even if I don't click "submit" (so that it should not fire check_username) . And the the form is always submitted no matter whether the username exists or not. What I want is, if the username exists, check_username will return false so that the form will not be submitted. could anyone tell me how to solve the problem? Thanks for your attention!

Community
  • 1
  • 1
  • Hey. You should read about asynchronicity.. – Ofir Israel Aug 30 '13 at 21:51
  • Yes. I know a little about it. But I used the deferred object, I think. I adopted the method in http://stackoverflow.com/questions/18541907/about-jquery-post-method – Jack Green Aug 30 '13 at 21:54
  • You should check the username as the user enters it not wait for them to post the form to check it. – Musa Aug 30 '13 at 21:54
  • @Musa I see. In that case, I must use the "blur" event. But, the problem is, if there is only one field (suppose only the username field) in the form, after the user input the username, he will press "submit", so there will be no way to fire the "blur" event. – Jack Green Aug 30 '13 at 22:00
  • I wasn't suggesting that would solve the problem, just that you should reduce any amount of time the user has to wait for the form to be submitted. Also if there is only one field I wouldn't even bother with that. – Musa Aug 30 '13 at 22:12

2 Answers2

1

$.post doesn't return a boolean value, so the result (a jqXHR object) will be converted to a boolean and be true, and thus the form will submit every time.

Update: Since the submit() method will trigger the onsubmit event even when it's invoked manually, you'll need to store the successful results from the $.post and add a condition in check_username().

One of many possible ways to accomplish this:

<form action="register/sumbit" method="post" onsubmit="return check_username()">
...
</form>

var isUsernameValid = false;

function check_username()
{
    if(isUsernameValid){
        return true;
    }else{
        $.post(url, data, successHandler); 
        return false; 
    }        
}

...

// in your $.post().done() handler...
if(data=="true"){ //username doesn't exist 
     isUsernameValid = true;
     $("form").submit();
}
user2680198
  • 306
  • 3
  • 4
0

It's never going to work that way. You're not going to get a synchronous return from an asynchronous operation.

What you can do is have the handler in check_username() submit the form on success.

<form action="register/sumbit" method="post" onsubmit="return check_username(this);">
...
</form>

function check_username(frm)
{
   var myform = $(frm);
   if (myform.data('checked'))  // already checked username? go ahead and submit
     return true;

   // otherwise, start the username check then return false

   // initialize url, data, etc.

   $.post(url, data, 
     function(data) {
       if (data == "true")
       {
         myform.data('checked', true);
         myform.submit();
       }
     }
   );

   return false;
}  
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
  • Thanks a lot. Your proposed method seems to be what I want. But I tried and found that if (data == "true"), it does not jump to the sumbit url. And I tested by adding an alert: – Jack Green Aug 30 '13 at 22:29
  • if (data == "true") {alert("good");$(frm).submit();} it will keep popping up "good" alert. – Jack Green Aug 30 '13 at 22:30
  • I don't understand why it keeps calling check_username(frm). Maybe because onsubmit="check_username(this); return false;" this way will cause check_username to be called all the time? – Jack Green Aug 30 '13 at 22:44
  • And if I change onsubmit to onsubmit="check_username(this); return true;" It only call check_username once. If it's "return false", then it will keep calling check_username. Is there a way to solve this? Thanks a lot! – Jack Green Aug 30 '13 at 23:09
  • I know where the problem is now. Because "$(frm).submit()" will fire onsubmit again. So it will keep running check_username(frm). Is there a way to solve this? – Jack Green Aug 31 '13 at 14:58
  • Edited the function to avoid that issue. – Paul Roub Aug 31 '13 at 22:23
  • Thanks Paul! I tested your code but it didn't submit. "myform.submit()" does not work. After I change it to "frm.submit()", it works. Maybe that's the solution. – Jack Green Aug 31 '13 at 22:49