Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery Event won't fire after ajax call

This is a rather strange issue with jquery. I am loading a div

<div id="container"> 

on page load. Each record is tabular data with a 'delete' ajax function associated with it. When the page loads and clicking the 'delete' link, the ajax call fires off just fine. However, once the event is fired, the data is returned from the ajax call, and the div is populated with data (but the page does not refresh or reload) When I click the link again, the ajax script will not fire. Here is my code:

$(document).ready(function() {     $("button.done").button({     }).click(function() {         var BatchID = $("input#BatchID").val();         var Amount = $("input#Amount").val();         var Name = $("input#CheckName").val();         var Check_Number = $("input#Check_Number").val();         var Company = $("select#Company").val();         var Department = $("select#Department").val();         $.ajax({             type: 'GET',             url: '/app/usagCheckEntryWS.html',             data: {                 "BatchID" : BatchID,                 "Amount" : Amount,                 "Name" : Name,                 "Check_Number" : Check_Number,                 "Company" : Company,                 "Department" : Department             },             success: function (data) {                     var ang = '';                     var obj = $.parseJSON(data);                     $.each(obj, function() {                        ang += '<table><tr><td width="45">' + this["RefID"] + '</td><td width="140">' + this["Name"] + '</td><td width="95">' + this["CheckNumber"] + '</td><td align="right" width="70">$' + this["Amount"] + '</td><td width="220" style="padding-left: 15px;">' + this["Description"] + '</td><td><div class="delete" rel="' + this["RefID"] + '"><span>Delete</span></div></td></tr></table>';                     });                     $('#container').html(ang);                     $("input#Amount").val('');                     $("input#CheckName").val('');                     $("input#Check_Number").val('');                     $("select#Company").val('MMS');                     $("th#dept").hide();                     $('input#CheckName').focus();             }         });     }); }); 

like image 547
Matthew Colley Avatar asked Dec 07 '12 17:12

Matthew Colley


People also ask

How run javascript after loading Ajax?

When the link li#menu-item-318 a gets clicked it removes the ready class which then reverses the css transition and then loads a new html document. On the Aja load I once again want to add the ready class to the same elements inserted by the Ajax call. The code below has a callback to add the ready class, which works.

How do you bind events on Ajax loaded content?

You need to use the event delegation for Ajax generated content using jQuery. Use jQuery delegation to attach an event in the dynamically created content by Ajax. The following code snippet shows you how to add/bind/use the jQuery click event on Ajax generated elements.

How can I call document ready function after Ajax call?

It would turn into: function OnloadFunction () { alert("test"); } $(document). ready(OnloadFunction); Then you can call OnloadFunction whenever you want to.


2 Answers

When you remove an element and then replace it (via javascript), it loses any event bindings that were added to it on page load.

(This also applies to content added to the page after page load - i.e. ajax loaded content)

There are several possible solutions for this.

1) Encapsulate your "binding" code and call it both on page load and immediately after the element in question gets added back to the page. For example:

$(document).ready(function(){     // bind event handlers when the page loads.     bindButtonClick(); });  function bindButtonClick(){     $('.myClickableElement').click(function(){         ... event handler code ...     }); }  function updateContent(){     $.ajax({         url : '/ajax-endpoint.php',         data : {'onMyWay' : 'toServer'},         dataType : 'html',         type : 'post',         success : function(responseHtml){             // .myClickableElement is replaced with new (unbound) html element(s)             $('#container').html(responseHtml);              // re-bind event handlers to '.myClickableElement'             bindButtonClick();           }     }); } 

2) The more elegant way to handle this: use jQuery's .on() method. With it, you are able to bind event handlers to elements other than the event target - i.e. an element that never gets removed from the page.

$(document).ready(function(){     $('body').on('click','.myClickableElement',function(){         ... event handler code ....     }); }); 

Some further explanation:

The .on() method uses event delegation to tell a parent element to retain your event handler code (3rd argument), and fire it when the event target (2nd argument) has a certain type of event (1st argument) performed on it.

If you are using a version of jQuery prior to 1.7 use the now deprecated delegate method which essentially does the same thing.

Also, it is worth noting that because of the way events "bubble up" through the dom tree, the event target (2nd argument of .on() method) must be a descendant of the delegating element (jQuery object's selector). For example, the following would NOT work

<div id="container-1">     <div>         <div id="another-div">             Some Stuff         </div>     </div> </div>  <div id="container-2">     <a id="click-me">Event Target!!!</a> </div>  <script type="text/javascript">     $('#container-1').on('click','#click-me',function(){         ... event handler code ....         // This will never execute, should've used '#container-2', or 'body', or 'document' instead of '#container-1'     }); </script> 

The body or document elements are usually safe choices since typically every element on the page is a descendant.

like image 118
Jason Fingar Avatar answered Sep 26 '22 06:09

Jason Fingar


You can enclose the event script in DIV and run a Replaceall command after dynamically loading the content.

<div class="somescript"> -- Event Script that you want to map with dnamically added content <div> 

-- Dynamically load your content and run the below command after it.

$(".somescript").replaceAll($(".somescript")); 

Once the dynamically loaded content is loaded and replace command has been run, the events will be mapped and code will run fine.

like image 41
Srikanth Srikanth Avatar answered Sep 24 '22 06:09

Srikanth Srikanth