7

I wrote the following code, which doesn't result in an AJAX call in my browser:

$(document).ready(function () {
  $('form').submit(function(event) {
    event.preventDefault();
    var action = $(this).attr('action');
    var data = $(this).serialize();
    $.post(action, data, function(response) {
      $("#die").html(response);
    });
  });
});

However, my instructor live-coded the following code in class, which does work:

$(document).ready(function () {
  $("form").on("submit", function(event) {
    event.preventDefault();
    var action = $(this).attr("action");
    var formData = $(this).serialize();
    $.post(action, formData, function(responseContent) {
      $("#die").html(responseContent);
    });
  });
});

As far as I can tell, the only meaningful difference between my code and his is the use of 'on' vs. 'submit' on line 2. In fact, on api.jquery.com/submit, the jQuery Foundation states that "This method is a shortcut for .on('submit', handler)...". Which leaves me confused as to why the two snippets behave differently.

Richie Thomas
  • 3,073
  • 4
  • 32
  • 55

3 Answers3

9

Note: .on() & .off() are the latest jQuery syntaxes at the time of writing (August 2014).

If you use jQuery 1.7 or above, methods .bind(), .delegate(), and .live() should not be used. The same applies for .unbind(), .undelegate(), & .die().


Introduction:

Similarly to jQuery's .on('click') vs .click() , using .on('submit') vs .submit() adds a number of advantages:

In the .on('click') vs .click() answer from andreister, he points out the memory usage being smaller, I expect the same for .on('submit') vs .submit().

But the much more significant advantages for .on('submit') vs .submit(), are some kind of "programmatical convenience":

  1. Working with dynamically added elements
  2. namespaces andreister also mentioned (that I pointed out in his answer's comments)

See some sample usages below to see how this all works.


Working with dynamically added elements: Sample usage 1

see live demo (click on Run/Clear in the top-right) on jsbin.com/puqahunovido/1/edit?html,js,console

Basically, you can tell jQuery to "observe" if a element has any of its children (direct or not) being submitted. This is particularly useful if you dynamically add new forms to this element. You then do NOT need to "re-hook" these new form to the jQuery handler.


Namespaces: Sample usage 1

see live demo (click on Run/Clear in the top-right) on jsbin.com/xalenefilifi/1/edit?html,js,console

/* bind form submission to 2 jQuery event handlers, each having a different namespace */
$(".js-form-hook-xyz").on("submit.hey", function() { console.log("hey!"); });
$(".js-form-hook-xyz").on("submit.hello", function() { console.log("hello!"); });

$(".js-form-hook-xyz").submit(); /* point 1: displays "hey!hello!" */

/* ... later in the code, unbind form submission for ONLY 1 handlers */
$(".js-form-hook-xyz").off("submit.hello");

$(".js-form-hook-xyz").submit(); /* point 2: displays "hey!" */

The result is that if the form is submitted at "point 1", both handlers are attached, hence called. And later on, at "point 2" handler "submit.hello" is not attached anymore so only the other handler triggers.


Namespaces: Sample usage 2:

see live demo (click on Run/Clear in the top-right) on jsbin.com/vubolacozuwe/1/edit?html,js,console

/* bind form submission to 2 jQuery event handlers, each having the SAME namespace */
$(".js-form-hook-xyz").on("submit.greetings", function() { console.log("Bonjour!"); });
$(".js-form-hook-xyz").on("submit.greetings", function() { console.log("Hola!"); });

$(".js-form-hook-xyz").submit(); /* point 1: displays "Bonjour! Hola!" */

/* ... later in the code, unbind form submission for ".greetings" namespace handlers */
$(".js-form-hook-xyz").off(".greetings");

$(".js-form-hook-xyz").submit(); /* point 2: displays nothing, handlers were removed */

The result is that if the form is submitted at "point 1", both handlers are attached, hence called. And later on, at "point 2" handler ".greetings" namespace handlers have been removed so nothing is displayed.


There might be even more cool sample usages I could think of for now so I will leave this for another time. Just look into the jQuery doc & search for similar topics on SO or Google. You'll find a bunch of interesting things I'm sure.

Resources:

  1. Difference between .on('click') vs .click()
  2. How to unbind a specific event handler
  3. http://api.jquery.com/on/#event-names
  4. api.jquery.com/on
  5. api.jquery.com/submit
reformed
  • 4,505
  • 11
  • 62
  • 88
Adriano
  • 19,463
  • 19
  • 103
  • 140
  • it depends on how you use `.on('submit'` - your first point `Working with dynamically added elements` - depends on if you are using the delegation form of .on() and will not bind to dynamically added elements using this form `$(".js-form-hook-xyz").on("submit.greetings",function()` – wirey00 Sep 03 '14 at 11:31
  • also as stated in my answer - `.submit(function())` will call `.on('submit'` internally – wirey00 Sep 03 '14 at 12:06
  • my point is that you can do things using `.on('submit',...)` that you can't do with `.submit(function(){})` even though yes `.on('submit',...)` will, on top of potentially do additional work, call `.submit(function(){})` internally. – Adriano Sep 03 '14 at 12:28
  • 1
    I guess that in the case of this specific question, since agentutah uses the simplest version of `.on('submit',...)` you are right. In that usage, here `.on('submit',function(){})`, it does the same as `.submit(function(){})` as it does not take advantage of delegation nor namespaces. – Adriano Sep 03 '14 at 12:31
5

If you look at the jQuery .submit() docs

This method is a shortcut for .on('submit', handler)

They behave the same

As you can see in jQuery's internal code, using the shorthand version will internally call .on()

jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
    "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
    "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {

    // Handle event binding
    jQuery.fn[ name ] = function( data, fn ) {
        return arguments.length > 0 ?
            this.on( name, null, data, fn ) :
            this.trigger( name );
    };
});
wirey00
  • 33,517
  • 7
  • 54
  • 65
1

You're right, these two should be working the same. The difference between $(form).submit and $(form).on(“submit”) is probably not the issue here. Check the console log and step through the code?

Mimi Flynn
  • 68
  • 1
  • 6