Ugy Astro
Ugy Astro

Reputation: 417

Click event only works on the first page when combined with jquery datatables, while the other pages do not work

Kinda hard to explain the problem, hopefully you can understand what I mean.

I have 1000 more data displayed by jquery datatables with this plugin pagination will automatically be created. In every line I add a css class so I could use for each row of data. Through this css class I use to call a javascript action as a dialogue. The problem, in the first page all goes well, but in the second to the last page I could not access the javascript action, dialogue does not appear, I check in console.log not indicate anything problematic.

This is my code :

HTML

<div id="dialog" title="Select one"></div>

PHP

foreach ($datafromDb as $data) {
    $datakey = '{"dataCode":"'.$data['dataCode'].'"}';
    echo "<td><a href='#' class='cssClass' data-key='" . $datakey . "'>Click</a></td>";
}

Javascript

$(document).ready(function () {
   // implement jquery dataTables
   $('#table').DataTable({
        bAutoWidth: false,
        stateSave: true
   });

   // this action executed when cssClass accessed
   $(".cssClass").click(function () {
        var self = this;

        $("#dialog").dialog({
            resizable: false,
            show: {
                effect: "bounce",
                duration: 500
            },
            hide: {
                effect: "explode",
                duration: 500
            },
            height: 100,
            modal: true,
            buttons: {
                "Button 1": function () {
                    var data = $(self).data('key');
                    window.open("http://www.example.com/" + "firstRoute" + "/" + data.dataCode, "_blank");
                },
                "Button 2": function () {
                    var data = $(self).data('key');
                    window.open("http://www.example.com/" + "secondRoute" + "/" + data.dataCode, "_blank");
                }
            }
        });
    });
}

Upvotes: 4

Views: 4077

Answers (4)

Abdullah
Abdullah

Reputation: 21

You need to specify the id of the parent element for instance

$("#example").on("click", "a.cssClass", function () {})

Upvotes: 0

Chris H.
Chris H.

Reputation: 2594

This is probably one of the most common DataTables errors/problems. So much so, in fact, that it is the second DataTables "most common FAQ". To quote Allan from DataTables FAQ:

Q: My events don't work on the second page

A. When attaching events to cells in a table controlled by DataTables, you need to be careful how it is done. Because DataTables removes nodes from the DOM, events applied with a static event listener might not be able to bind themselves to all nodes in the table. To overcome this, simply use jQuery delegated event listener options, as shown in this example.

I'd recommend taking a look at that example page, but to summarize what it says: because DataTables adds and removes rows from the DOM as needed, events may fail, especially on pages after the first (since they weren't on the page when the DataTables button events were loaded).

The workaround to this is to use the JQuery on event listener for row events. You can use the DataTables row().data() call to get the data for the selected/clicked row. In your case it would probably look something like this:

$('#table').on('click', 'tr', function () {
    var data = table.row( this ).data();

    $("#dialog").dialog({
        resizable: false,
        show: {
            effect: "bounce",
            duration: 500
        },
        hide: {
            effect: "explode",
            duration: 500
        },
        height: 100,
        modal: true,
        buttons: {
            "Button 1": function () {
                window.open("http://www.example.com/" + "firstRoute" + "/" + data('key').dataCode, "_blank");
            },
            "Button 2": function () {
                window.open("http://www.example.com/" + "secondRoute" + "/" + data('key').dataCode, "_blank");
            }
        }
    });
});

As a side note, is there a reason you are adding a CSS class to every row just to call events on instead of just attaching the events to the rows themselves, like in this example?

Upvotes: 1

annoyingmouse
annoyingmouse

Reputation: 5699

Alternatively you could add the event listener to the table itself:

$('#table').on("click", ".cssClass", function(){
    var self = this;
    $("#dialog").dialog({
        resizable: false,
        show: {
            effect: "bounce",
            duration: 500
        },
        hide: {
            effect: "explode",
            duration: 500
        },
        height: 100,
        modal: true,
        buttons: {
            "Button 1": function () {
                var data = $(self).data('key');
                window.open("http://www.example.com/" + "firstRoute" + "/" + data.dataCode, "_blank");
            },
            "Button 2": function () {
                var data = $(self).data('key');
                window.open("http://www.example.com/" + "secondRoute" + "/" + data.dataCode, "_blank");
            }
        }
    });
});

The cssClass class is only available to jQuery on the first page, subsequent cells are not yet in the DOM so will not have the event listener attached. Hope that helps.

Upvotes: 3

Anson
Anson

Reputation: 489

It seems re-draw the data table. So that you have to bind click event again with the function. At first, assign your data table to a variable. Like this:

var dt = $('#table').DataTable({
    bAutoWidth: false,
    stateSave: true
});

Then, bind draw event and move your click binding code into the callback function. Like this:

dt.on('draw', function() {
   $(".cssClass").click(function () {
       // The callback function.
   });
});

Reference: https://datatables.net/manual/events

Upvotes: 2

Related Questions