Подтвердить что ты не робот

JQuery DataTables - строка не регистрируется на страницах, кроме первых

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

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

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

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

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

Как таковой, есть кто-нибудь:

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

Приветствия

4b9b3361

Ответ 1

У меня была эта проблема в одностраничном приложении. Живой метод работал у меня кроме после обратной передачи. Моя таблица была заполнена через 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' );
        }
    } );
} );

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

Так как 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
});

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

Ответ 5

Мой ответ подобен тому, что у @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's) в таблице -

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

                           }
                    } );