jQuery DataTables – Haga clic en la fila para no registrarse en otras páginas que no sean la primera

Estoy usando DataTables jQuery y tengo una configuration de administrador de clics en el clic de fila de la siguiente manera:

$('#dt tbody tr').click(function () { alert('e'); }); 

Esto funciona perfectamente para la primera página de resultados de DataTables.

Sin embargo, cuando me muevo a otra página de resultados, el manejador de clics ya no se registra.

Mi presunción es que el código DataTables está deteniendo la propagación del evento click a mi controller, pero como esto solo ocurre en páginas posteriores al primero, parece inusual.

Como tal, tiene alguien:

  1. Encontrado (e idealmente resuelto) este problema
  2. Encontré una buena manera de rastrear la propagación de events de jQuery / JS para aislar por qué se detiene el evento

Aclamaciones

Tuve este problema en una aplicación de una sola página. El método en vivo funcionó para mí, excepto después de una devolución de datos. Mi tabla fue poblada a través de ajax, y el usuario podría causar que se destruya y recree.

Para solucionarlo, utilicé dataTables. $: "http://datatables.net/api#$"

Aquí está mi solución usando el ejemplo DataTables give para la function de fila oculta.

 $(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' ); } } ); } ); 

Supongo que el enlace del controller de events se aplica solo a las filas cargadas inicialmente. Pero una vez que la colección de filas se vuelve a representar en el marcado, los controlleres de events ya no existen.

Mira la function live () de jQuery. La key es que los controlleres de events están destinados a todos los elementos que cumplen los criterios de selección "ahora y en el futuro".

Tuve el mismo problema con los botones en todas las filas de DataTables, el evento click no funcionó en ningún button después de la primera página de resultados. Kon dio el análisis correcto (gracias Kon), pero para aquellos que buscan un código de ejemplo, esto es lo que funcionó para mí:

 $('.myButton').live('click', function() { var id = $(this).closest("tr").attr("id"); var string = 'div_id=' + id; alert(string); // string sent to processing script here }); 

¡Espero que ayude!

Como Live ahora está en desuso, sugiero usar '.on'.

Esto debería solucionar tu problema:

 $(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 }); 

Puede intercambiar documentos con algún elemento principal ya que no es muy eficiente. Tal vez intente usar un div que contenga su tabla.

Mi respuesta es similar a la de @Chris Everitt, con una ligera diferencia. Solo para aquellos que quieran verlo … aquí va …

  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 } ] }); 

Registro de evento para todos los img (dom attr) en la tabla –

  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'); } } );