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.
I’m from Indonesia, thank you very much, it’s working.
Thank you, works perfectly !
Thank you ! Perfect solution 🙂
Thank you very much! ! ! From Azerbaijan! ! !
Thank you very much it worked.
Thank you very much for ur solution…! 🙂
you rock, thank you!!!
Hi Michael, I have a question about the table. It looks like you gave it a class “table-hover”. I wonder if you made it “table-single-row-select”? Cuz I did it to my table but my click on any row does not select the row. It’s annoying me so badly. Do you know what would the cause be? Thanks a lot.
Not sure, if I understand your question. This example doesn’t demonstrate single row selection, see Single item selection for that.
Michael,
Hey there, thanks for taking the time to explain this to me. I have a question though, does this not allow us to preventDefaults? I have a form that’s loaded via pagination and now I encounter a new problem of the button responding, but refreshing the page instead of doing an Ajax request like I’d like.
Thanks for taking the time to respond~!
It sounds from your description than your button is a submit button. Just change it to regular button by adding
type="button"
and it will not submit your form.Michael,
Thanks for taking the time to respond again. I tried that as soon as I read your comment.
I made a short video to showcase my problem if you don’t mind watching(1 min)
http://www.youtube.com/watch?v=acT2qyujA5g
The initial run of the code works as expected, the comment button focuses the comment form(sorry forgot to show this in the video), and the reply buttons reveal the reply to comment form.
However, whenever I scroll down and grab additional post’s via pagination, the desired behavior isn’t there. The anchor link type button doesn’t preventDefault and reloads the page.
I managed to workaround this via creating a function, grabButtons(), and putting this code inside of it, after Ajax returns the additional posts I fire it again. However, this isn’t a great solution either because the result of this is that some of the reply buttons will work whereas others won’t.
Here’s the code I show in the video:
https://gist.github.com/PrimeTimeTran/f5bfe124495f5faf4a0f3e20a15239f1
Here’s my solution which is lackluster:
https://gist.github.com/PrimeTimeTran/1d72860b8af20df13bc54b365f2801e3
Thanks for taking the time once again for not only writing this post to give the world and myself better insight into what’s going on as well as responding!
Hi !
I just had this problem and I thought I might give you the other solution :
just swap the sequence between jquery selector and the datatable init.
1. this is the problem
2. this is the solution
Thanks, took me an hour trying to figure this, you are the savior!
🙂
Thank you very much!
Perfect explanation!
Awesome! Worked for me 🙂
Sir, thank you so much! You just save my day! God bless!
Thanks, this is a great Help!!!
Thanks ! great help !!
.
How to change this style for data table?
help
$(document).ready( function () {
$(‘#myTable’).DataTable({
“lengthMenu”: [[5,10, 25, 50, -1], [5, 10, 25, 50, “All”]],
“columnDefs”: [
{
“targets”: [“not-search-orderable”],
“searchable”: true,
“orderable”: true,
‘autoWidth’:false
},
{
“targets”: “_all”,
“className”: “dt-body-center”
}
]
});
} );
I’m just here to Thank You sooo soooo much!
xo
Thanks, dude.