jQuery DataTables - Строка клика не регистрируется на страницах, отличных от первой - PullRequest
17 голосов
/ 13 мая 2011

Я использую плагин DataTables jQuery , и у меня настроен обработчик щелчка по щелчку строки следующим образом:

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

Это прекрасно работает для первой страницы результатов DataTables.

Однако, когда я перехожу на другую страницу результатов, обработчик щелчков больше не регистрируется вообще.

Я предполагаю, что код DataTables останавливает распространение события click на мой обработчик, но так как это происходит только на страницах после первой, это кажется необычным.

Как таковой, имеет кого-либо:

  1. Обнаружена (и в идеале решена) эта проблема
  2. Найден хороший способ отследить распространение события jQuery / JS, чтобы определить причину остановки события

Приветствия

Ответы [ 5 ]

12 голосов
/ 13 мая 2011

Я предполагаю, что привязка обработчика событий применяется только к первоначально загруженным строкам. Но как только коллекция строк перерисовывается в разметке, обработчиков событий больше нет.

Проверьте функцию jQuery live () . Ключ к тому, что обработчики событий привязаны ко всем элементам, отвечающим критериям селектора «сейчас и в будущем».

11 голосов
/ 04 декабря 2012

У меня была эта проблема в одностраничном приложении.Живой метод работал для меня за исключением после обратной передачи.Моя таблица была заполнена с помощью ajax, и пользователь мог вызвать ее уничтожение и воссоздание.

Чтобы исправить это, я использовал dataTables. $: "http://datatables.net/api#$"

Вот мое исправление с использованием примера DataTablesдля функции скрытого ряда.

$(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' );
        }
    } );
} );
5 голосов
/ 21 апреля 2012

У меня была та же проблема с кнопками во всех моих строках DataTables, событие нажатия не работало ни на одной кнопке после первой страницы результатов.Кон дал правильный анализ (спасибо Кон), но для тех, кто ищет пример кода, вот что сработало для меня:

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

Надеюсь, это поможет!

3 голосов
/ 30 августа 2013

Поскольку live сейчас устарела, я предлагаю использовать '.on'.

Это должно решить вашу проблему:

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

Вы можете обменять документ с некоторым родительским элементом, поскольку он не очень эффективен. Возможно, попробуйте использовать div, содержащий вашу таблицу.

1 голос
/ 23 апреля 2014

Мой ответ похож на ответ @Chris Everitt, с небольшой разницей. Просто для тех, кто хотел бы увидеть это .. вот оно ..

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

            });

Регистрация события для всех img (dom attr) в таблице -

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

                           }
                    } );    
...