10

I have two submit handlers, one validating a form and one submitting the form:

// validates the form but does not submit it
$("form").submit(function() {
  // perform validation here and set "validationFails" appropriately
  // ...
  if (validationFails) {
    return false;
  }
});

// submits the form via ajax
$("form").submit(function(event) {
  event.preventDefault();
  // submit the form via ajax here
  // ...
});

It seems like the form should not be submitted via ajax if validation fails because return false is used, and so the subsequent submit handler in the chain should not be called. However, even if validation fails, the form is submitted via ajax. Why?

Donald T
  • 10,234
  • 17
  • 63
  • 91
  • have you tried stepping through the code in a debugger like Firebug or Chrome Developer? – TimCodes.NET Feb 27 '12 at 19:56
  • why complicate things by using two form submit handlers, just create one and add any function calls to it - http://stackoverflow.com/questions/290254/how-to-order-events-bound-with-jquery – scibuff Feb 27 '12 at 19:57
  • 1
    This is in a large Web app that uses common validation across the app (hence the first submit handler), and uses a specific submission handler for the specific section of the app (hence the second handler). The handlers are in different files, and the first handler shown above is loaded and attached first. – Donald T Feb 27 '12 at 20:00

3 Answers3

20

Returning false from an event handler is the equivalent of calling both event.preventDefault() and event.stopPropagation(), that is, it prevents the default action for the event from happening and it stops the event bubbling up the DOM tree. It does not stop other handlers on the same element from running.

You need to call the event.stopImmediatePropagation() method - that stops other handlers bound to the same element from running, noting that the handlers will be run in the same order they are bound so you (obviously) have to bind your validation handler first.

$("form").submit(function(event) {
  // perform validation here and set "validationFails" appropriately
  // ...
  if (validationFails) {
      event.stopImmediatePropagation();
      return false;
  }
});
nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • is there a way to let the other handlers resume, after "stopImmediatePropagation" and do some work? – emfi Oct 23 '13 at 08:55
  • @emfi - Where would you try to do that from? After the handler in which `stopImmediatePropagation()` is called finishes that will be the end of processing for the current event. – nnnnnn Oct 23 '13 at 09:19
  • ah, okay... i would like to something like that: replace the current handler with another one, and if the new one is completed, re-bind and trigger the old one – emfi Oct 23 '13 at 11:06
  • How can I make sure the second handler is called **after** the validation one? – Augustin Riedinger Oct 30 '14 at 22:09
  • @AugustinRiedinger - as I said in my answer, jQuery calls the handlers in the order they were bound. – nnnnnn Oct 30 '14 at 22:54
0

You are missing event argument in the second submit handler and also you need to stop the event propagation from first submit handler when validation fails.

$("form").submit(function(event) {
  // validate...
  if (validationFails) {
      event.stopPropagation();
      return false;
  }
});

$("form").submit(function(event) {
      event.preventDefault();
     // submit the form via ajax
});
ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
-3

Your logic is incorrect that the 2 handlers are talking to each other. Use only one handler. Return false if validation fails, submit via ajax if it doesn't fail

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • 2
    This is in a large Web app that uses common validation across the app (hence the first submit handler), and uses a specific submission handler for the section of the app (hence the second handler). The handlers are in different files, and the first handler shown above is loaded and attached first. – Donald T Feb 27 '12 at 20:00
  • WOuld be better then to unbind "submit" then bind one handler to manage the process – charlietfl Feb 27 '12 at 20:08