2011-05-12 32 views
17

estoy usando el DataTables jQuery Plugin y tienen una configuración Haga clic manejador en el corredor de la siguiente manera:DataTables jQuery - Fila clic no se registra en otras páginas distintas de primera

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

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

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

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

Como tal, tiene a nadie:

  1. encontrado (e idealmente resuelto), este problema
  2. encontrado una buena manera de seguir jQuery/JS propagación de eventos para aislar por qué el evento se detuvo

Cheers

+0

Mi suposición era incorrecta. Otra presunción no declarada: que el enlace en 'ajaxComplete' se uniría a todas las filas, no era válido ya que DataTables es prudente y no representa todas las filas en el navegador hasta que sea necesario. Como tal, la respuesta de Kon de 'live()' es correcta. –

+0

Mire la respuesta proporcionada por Chris Everitt. Utiliza una función DataTables incorporada y NO usa funciones jquery obsoletas. – Nullius

Respuesta

11

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 he usado DataTables $:. "http://datatables.net/api#$"

Aquí es mi arreglo mediante el ejemplo DataTables dan para la función 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'); 
     } 
    }); 
}); 
+0

Esta debería ser la respuesta aceptada. Usar funciones obsoletas como jquery live() nunca es una buena idea. Simplemente use tableVariable. $ ('tr') en lugar de $ ('# tableId tr') como usted dijo. +1 – Nullius

+0

Actualizado, gracias. –

+0

Esto también resolvió mi problema similar al tratar de usar una técnica sugerido en esta publicación de blog: http://ricardocovo.com/2010/09/02/asp-mvc-delete-confirmation-with-ajax-jquery-ui-dialog/ (es decir, utilizando la técnica de diálogo de confirmación de eliminación junto con tablas de datos jQuery); ... los enlaces de eliminación dejaron de funcionar en páginas posteriores a la primera página; así que en lugar de usar $ ('delete-link'), haga clic en (function() etc ..., utilicé la idea anterior para solucionar el problema, diciendo: oTable. $ ('. delete-link'). on ('click', function() {...}; en ese punto, los enlaces de eliminación comenzaron a funcionar nuevamente. –

12

Supongo que el enlace del controlador de eventos 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 controladores de eventos ya no existen.

Echa un vistazo a la función live() de jQuery. La clave es que los controladores de eventos están destinados a todos los elementos que cumplen los criterios de selección "ahora y en el futuro".

+0

Derecho, por supuesto, aplausos. Extraño funcionó en la primera página (todas las filas se cargan dinámicamente) pero, no obstante, creo que esta es la respuesta. Confirmaré y acepto en breve. –

+2

Eso tiene sentido si carga las filas ANTES de definir el controlador click(). – Kon

+0

Por supuesto, puse el 'click' en mi controlador' ajaxComplete' pensando que DataTables estaba cargando todas las filas y simplemente ocultándolas. Sin embargo, eso solo se adhiere a la primera página porque eso es todos los renders de DataTables (el resto se mantiene en la memoria). Haciéndolo '$ ('# dt tbody tr'). Live ('click', function()' etc. lo arregla (y de hecho puede declararse fuera del 'ajaxComplete' debido al bit" ahora y en el futuro " usted menciona. –

5

Tuve el mismo problema con los botones de todas mis filas de DataTables, el evento click no funcionó en ningún botón después de la primera página de resultados. Kon dio el análisis correcto (gracias Kon), pero para aquellos que buscan ejemplo de código, 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!

+0

Gracias. Código con la respuesta siempre es útil – bladefist

+0

¡gracias funciona perfectamente! no funcionó. – rashid

3

Dado que el tiempo de vida útil ahora es obsoleto, sugiero usar '.on'.

Esto debería resolver su 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 documento con algún elemento padre, ya que no es muy eficiente. Tal vez intente usar un div que contenga su tabla.

1

Mi respuesta es similar a la de @Chris Everitt, con una pequeña 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 } 
      ] 

      }); 

evento de registro para todos img (attr dom 's) 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'); 

          } 
        });  
Cuestiones relacionadas