I'm using the DataTables jQuery Plugin and have a click handler setup on row click as follows:
$('#dt tbody tr').click(function () {
alert('e');
});
This works perfectly for the first page of DataTables results.
However, when I move to another page of results, the click handler no longer registers at all.
My presumption is that the DataTables code is stopping the propogation of the click
event to my handler, but as开发者_开发技巧 this is only occurring on pages after the first it seems unusual.
As such, has anyone:
- Encountered (and ideally resolved) this problem
- Found a good way to track jQuery/JS event propogation to isolate why the event is being stopped
Cheers
I'm guessing the event handler binding is being applied only to the initially loaded rows. But once the row collection gets re-rendered in the markup, the event handlers are no more.
Check out jQuery's live() function. The key there being that event handlers are bound for all elements meeting selector criteria "now and in the future."
I had this problem on a single page application. The live method worked for me except after a postback. My table was populated via ajax, and the user could cause it to be destroyed and recreated.
To fix it I used dataTables.$: "http://datatables.net/api#$"
Here is my fix using the example DataTables give for the hidden row function.
$(document).ready(function() {
/*
* Insert a 'details' column to the table
*/
var nCloneTh = document.createElement( 'th' );
var nCloneTd = document.createElement( 'td' );
nCloneTd.innerHTML = '<img src="../examples_support/details_open.png">';
nCloneTd.className = "center";
/* CHANGE: Remove all the expand control elements we may have added earlier
* or else you'll add a new column for every postback
*/
$('.expand-control').remove();
/*
* CHANGE: Add the expand-control class to these elements,
* so we can remove them after a postback
*/
$(nCloneTh).addClass('expand-control');
$(nCloneTd).addClass('expand-control');
$('#example thead tr').each( function () {
this.insertBefore( nCloneTh, this.childNodes[0] );
} );
$('#example tbody tr').each( function () {
this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] );
} );
/*
* Initialse DataTables, with no sorting on the 'details' column
*/
var oTable = $('#example').dataTable( {
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0 ] }
],
"aaSorting": [[1, 'asc']]
});
/* Add event listener for opening and closing details
* Note that the indicator for showing
* which row is open is not controlled by DataTables,
* rather it is done here
*/
/* CHANGE: Here I use jQuery.dataTable.$ instead of
* jQuery('#example tbody td img'),
* this is what preserves the event handler on the 2nd (etc)
* pages after a postback
* Note the use of on instead of live, recommended over live as of 1.7
*/
oTable.$('tr').find('img').on('click', function () {
var nTr = $(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "../examples_support/details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row */
this.src = "../examples_support/details_close.png";
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
}
} );
} );
I had the same issue with buttons in all of my DataTables rows, the click event didn't work on any buttons after the first page of results. Kon gave the correct analysis (thank you Kon), but for those looking for example code, here's what worked for me:
$('.myButton').live('click', function() {
var id = $(this).closest("tr").attr("id");
var string = 'div_id=' + id;
alert(string);
// string sent to processing script here
});
Hope that helps!
Since live is now deprecated, i suggest using '.on'.
This should solve your problem:
$(document).on('click', '.myButton', function() {
var id = $(this).closest("tr").attr("id");
var string = 'div_id=' + id;
alert(string);
// string sent to processing script here
});
You can exchange document with some parent element as it is not very efficient. Perhaps try using a div containing your table.
My answer is similar to that of @Chris Everitt, with a slight difference. Just for those who would like to see it.. here it goes..
var oTable = $('#masterTable').dataTable( {
"aLengthMenu": [[5,10, 25, 50, 100 , -1], [5,10, 25, 50, 100, "All"]],
"iDisplayLength" : 10,
"aoColumnDefs": [
{"sWidth": "25%", "aTargets": [ 0 ] },
{"sWidth": "10%", "aTargets": [ 1 ] },
{"sWidth": "10%", "aTargets": [ 2 ] },
{"sWidth": "10%", "aTargets": [ 3 ] },
{"sWidth": "10%", "aTargets": [ 4 ] },
{"sWidth": "10%", "aTargets": [ 5 ] },
{"sWidth": "15%", "aTargets": [ 6 ] },
{"sClass": "align-left" , "aTargets": [ 0,1,4, 2,3,5,6] }
],
"aoColumns": [
{ "bSortable": true },
null, null, null,null, null,
{ "bSortable": true }
]
});
Registering event for all img (dom attr's) in the table -
oTable.$('td').each( function () {
$(this).on('click','img', function () {
var nTr = $(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "${pageContext.request.contextPath}/theme/v_1_0/app-images/details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row */
this.src = "${pageContext.request.contextPath}/theme/v_1_0/app-images/details_close.png";
var html = '<div> Placeholder here.. </div>';
oTable.fnOpen(nTr, html, 'details');
}
} );
精彩评论