This is one of the most common problems users have with jQuery DataTables plug-in and it has very simple solution if you understand why it occurs.
Problem
Table below demonstrates the problem with attaching event handlers incorrectly. Clicking on “Edit” button should open a modal dialog.
Event handler is attached as follows:
$('#example .btn-edit').on('click', function(){
// ...
});
However if you go to a different page, sort or filter the table, “Edit” button stops working for those records that were previously hidden.
Cause
After the table is initialized, only visible rows exist in Document Object Model (DOM). According to jQuery on() documentation:
Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to
.on()
Our code above worked only for the first page elements because elements from other pages were not available in DOM at the time the code was executed.
Solution
The solution is to use event delegation by providing selector for target element as a second argument in on() call, see example below. According to jQuery on() documentation:
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.
$('#example').on('click', '.btn-edit', function(){
// ...
});
We attach event handler to the table '#example'
and specify a selector for the button '.btn-edit'
as an additional parameter for on() method. Event handler will now be called for all buttons whether they exist in DOM now or added at a later time.
Table below demonstrates the working solution.
Thanks a lot. This has saved my day!
Thanks!
Thank you sooo much sir!
A 2015 post has finally given me a clue…your code sample isn’t identical to mine, but the problem is. I have a function call to a .change when a select box is changed. Works on the first page, not on subsequent. The
.on
samples you have don’t work and changing to.change
or.on ('change',...
etc don’t work.Code:
Thoughts? What am I missing?
Please use the following pattern:
Using
id
attributecloseStatus
for more than oneselect
element is not recommended, you need to useclass
instead.For example, for table with ID
example
and multipleselect
elements with classcloseStatus
:How are you reading table data on modal show?
I want to read data.
I will publish this example on JSFiddle sometimes today or tomorrow so that it would be easier to see the code.
I updated the article with examples on JSFiddle so it would be easier to see the source code.
My problem was similar to @Chad M and your answer worked for me. Thank you so much @Michael Ryvkin !
Excellent – was exactly what I needed
can you give some examples:
Load the datatables on click event.?
Perfect! Ty
Very GOOD! Thank you!
Searched for “jquery dataTables click function” and found this. Thank you very much!
good one mate
This is the most concise, succinct discussion/answer to this problem that I’ve ever seen. Thanks! DataTables in general and pagination in particular has caused me countless hours of frustration.
Thank you for your kind words!
I wonder if you have an answer to the issue of pagination on (for instance) page 4 jumping back to page 1 when some a checkbox is clicked (and thus the form is submitted). I’ve seen the “stateSave: true” thing but that causes it to **always** be on whatever page it’s on, even when I go to another part of the site and then come back. Just asking, so I appreciate any insight you can provide.
Hello Micheal,
Very clean code you’ve got here.
I have a scenario where the data for the table is generated from a database in a .Net core environment. What i need is implement the EDIT or DETAILS button to display records in a modal popup on clicking the button on a row.
I pull data via a controller action. It works very well when i use normal tables in a Razor form. Trying to get a good example using jQuery datatables.
Would really appreciate if you could help with this.
Regards,
George.
..Again Micheal,
To buttress my question, i load data with an Ajax call to display tabular records in Datatables. I see the records you have in the example above were pre-filled..
Hope to hear from you soonest.
Regards…
George
Holy *** u saved me *** month!!! Thx a lot man!
Awesome help man. You saved my entire project man.
THANK YOU VERY MUCH
MUCHAS GRACIAS
Thank You Very Much
GBU
Thank you very much. This helped me a lot.
Your working example doesn’t seem to be working on Firefox or Chrome? Has something changed? Might be time to update this article.
Regards,
George Geschwend
I take my comment back! It works on BOTH examples if you are talking about the Edit button on each row. I was able to fiddle with the rows and the popup menu appears in both your working example and the non-working example.
It works only on the FIRST page in the non-working example and on EVERY page in the working example.
Michael —
I clicked on the JS Fiddle link above the first non working example… and it looks like the code is
$(‘#example’).on(‘click’, ‘.btn-edit’, function(){//looked like the working code you described.
// Reset form
$(‘#form-edit’).get(0).reset();
// Store current row
$(‘#modal-edit’).data(‘row’, $(this).closest(‘tr’));
// Show dialog
$(‘#modal-edit’).modal(‘show’);
});
I then replaced the $(‘#example’).on(‘click’, ‘.btn-edit’, function(){
with:
$(‘#example .btn-edit’).on(‘click’, function(){
..and saved it in fiddle.
I then returned to the web-page… and when I went to the 1st example the on-click function went to the second page of the table, and it behaved as you described in the problem statement.
I returned the code to what you had. I am not that familiar with JSFiddle… so my guess is… that’s the working code is some how linked to your first pre-fix example. Maybe my meds aren’t working today and I am hallucinating …. dunno …please excuse me if I am. 🙂
George
George, you’re absolutely right! The first example demonstrating the problem already had corrected code, not sure how’s that happened. Thank you for spotting the issue!
I updated the non-working example code to use the
$(‘#example .btn-edit’).on(‘click’, function(){
to demonstrate the problem.