9

I'm wanting to use AJAX to determine whether or not a form's values are acceptable to me (this is not form validation). The AJAX result will determine if the form is submitted or not.

Below, you'll see that I perform an AJAX call when the form is submitted and depending what is returned (either blank which is acceptable, or an error message which is not acceptable), I'd like to return true; or return false; the $("form").submit.

I suspect my trouble to be in the AJAX's success:. Please help me get the result out of the AJAX call so that I can do something like if (result == "") { return true; } else { return false; }.

WORKING:

$("form").submit(function(e) {
    e.preventDefault();
    var form = this;
    var tray = $('select[name=tray_id]').val();
    $.ajax({
        type: "POST",
        url: "modules/reserve-check.php",
        data: {tray_id: tray},
        cache: false
    }).done(function(result) {
        if (result == "")
            form.submit();
        else
            alert(result);
    }).fail(function() {
        alert('ERROR');
    });
});

ORIGINAL:

$("form").submit(function() {
    var tray = $('select[name=tray_id]').val();
    $.ajax({
        type: "POST",
        url: "modules/reserve-check.php",
        data: {tray_id: tray},
        cache: false,
        success: function(result) {
                alert(result);
        },
        error: function(result) {
            alert(result); //This works as expected (blank if acceptable and error msg if not acceptable)
        }
    });

    /*
    if (result == "")
        return true; 
    else
        return false; 
    */
    return false; //this is here for debugging, just to stop the form submission
});
Solid I
  • 580
  • 5
  • 13
  • 34
  • 1
    Why not just submit the whole form to the server with an AJAX call and let the server decide what is acceptable. Then you can have the server return a success or error code and you can act accordingly –  Jun 13 '13 at 21:24
  • You can only return from synchronous code, Ajax is asynchronous. Read the post above and work with callbacks. – Fabrício Matté Jun 13 '13 at 21:32
  • Further to what Mike W said, if you do do a pre-submit acceptability test via Ajax you really need to repeat the test within the PHP code you then submit to, in case the user had JS disabled or otherwise managed to bypass your submit handler. – nnnnnn Jun 13 '13 at 21:33

2 Answers2

23

As the ajax call is asynchronous, you have to prevent the form from submitting, and then when a result is returned, you check if it matches the condition and submit the form with the native submit handler, avoiding the preventDefault() in the jQuery event handler :

$("form").submit(function(e) {
    e.preventDefault();

    var self = this,
        tray = $('select[name=tray_id]').val();

    $.ajax({
        type: "POST",
        url: "modules/reserve-check.php",
        data: {tray_id: tray},
        cache: false
    }).done(function(result) {
        if (result == "") self.submit();
    }).fail(function() {
        alert('error');
    });
});
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • and also `$("form").off('submit')` would be fine – claustrofob Jun 13 '13 at 21:35
  • @claustrofob - No it wouldn't. That doesn't cause a submit. – nnnnnn Jun 13 '13 at 21:36
  • @nnnnnn you are right. It is a native DOM object. – claustrofob Jun 13 '13 at 21:41
  • If I use $("form").submit() instead of self.submit() the console shows that the ajax call runs forever! Could you please explain why this happens? By the way, thanks for the answer. +1 – hex494D49 Apr 21 '16 at 15:42
  • 2
    @hex494D49 - It happens because the jQuery event handler cathes the `submit` event. In other words, when you do `$("form")` you end up in the `$("form").submit(function() {...})` event handler, which in turns tries to submit the form again, ending up in the same event handler, which in turn trues to submit the form again, ending up in the same event handler ... and so on. When you call the **native** `form.submit()`, which isn't a jQuery function, the event handler isn't triggered, and the form is submitted. – adeneo Apr 21 '16 at 18:43
  • @adeneo I've got it :) Thanks a lot! – hex494D49 Apr 22 '16 at 09:31
  • brief and to the point! – Aris Jun 21 '16 at 11:56
  • @adeneo This is by far the most elegant solution to the callback hell! Thank you very very much! – timmi4sa Apr 26 '23 at 16:12
3

use e.preventDefault(); to prevent the form from submitting, and then use this.submit() (isn't calling the jQuery .submit() trigger function, but rather the native <form> .submit() function) to submit the form.

$("form").submit(function(e) {
            e.preventDefault();
            var tray = $('select[name=tray_id]').val();
            var form = this;
            $.ajax({
                type: "POST",
                url: "modules/reserve-check.php",
                data: {tray_id: tray},
                cache: false,
                complete : function(result){callback(result, form)}
            });       
        });

var callback = function(result, form){
  if(!result)
    form.submit();
};
Ouadie
  • 13,005
  • 4
  • 52
  • 62