134

I've got a problem with .on(). I have multiple form-elements (forms with class="remember"), also I add another one form.remember using AJAX. So, I want it to handle submit event something like:

$('form.remember').on('submit',function(){...}) 

but form added with AJAX doesn't work with it.

Where is the problem? Is it a bug?

simhumileco
  • 31,877
  • 16
  • 137
  • 115
Anton Abramov
  • 2,251
  • 6
  • 24
  • 27

3 Answers3

270

You need to delegate event to the document level

$(document).on('submit','form.remember',function(){
   // code
});

$('form.remember').on('submit' work same as $('form.remember').submit( but when you use $(document).on('submit','form.remember' then it will also work for the DOM added later.

Dipesh Parmar
  • 27,090
  • 8
  • 61
  • 90
  • 29
    Also bear in mind that `$(document).on` has much lower performance than `$('form.remember').on('submit'`. It now has to listen for **all** submit events in the document. It's much better to restrict the scope a little than listen `on` `document`, if possible – Liam Nov 04 '14 at 10:03
  • 9
    $('body').on('submit','form.remember',function(){ // code }); solved my problem – Olotin Temitope Jan 18 '17 at 04:22
  • Even though @Liam is correct, $(document).on is still useful for CRUD operations on ajax rendered elements. – Norielle Cruz May 15 '20 at 09:05
53

I had a problem with the same symtoms. In my case, it turned out that my submit function was missing the "return" statement.

For example:

 $("#id_form").on("submit", function(){
   //Code: Action (like ajax...)
   return false;
 })
Vítor Oliveira
  • 1,851
  • 18
  • 23
  • 4
    Note that `return false;` will not submit the form. For submitting the form use `return true;`. – Avatar Mar 23 '20 at 05:19
  • 1
    If he uses ajax - submission will be done by ajax, later on 200 http status just will do intended activities. So return false will be useful. – John Jul 14 '21 at 13:27
0

The problem here is that the "on" is applied to all elements that exists AT THE TIME. When you create an element dynamically, you need to run the on again:

$('form').on('submit',doFormStuff);

createNewForm();

// re-attach to all forms
$('form').off('submit').on('submit',doFormStuff);

Since forms usually have names or IDs, you can just attach to the new form as well. If I'm creating a lot of dynamic stuff, I'll include a setup or bind function:

function bindItems(){
    $('form').off('submit').on('submit',doFormStuff); 
    $('button').off('click').on('click',doButtonStuff);
}   

So then whenever you create something (buttons usually in my case), I just call bindItems to update everything on the page.

createNewButton();
bindItems();

I don't like using 'body' or document elements because with tabs and modals they tend to hang around and do things you don't expect. I always try to be as specific as possible unless its a simple 1 page project.

Danial
  • 1,496
  • 14
  • 15
  • Not really. Rather use $(document).on('submit','form',function(e) {...}); Then no need to 'reattach' – Gavin Simpson Apr 02 '21 at 09:41
  • 1
    I specifically said I don't like to do it on a global, document level. For a small, single page project this may be fine; but if you have a lot of different modules with their own forms global handlers create a lot of extra clicks and debugging problems if your code isn't targeted to specific forms. – Danial Apr 02 '21 at 16:20