Click event of row in table: First click not fire

Click event of row in table: First click not fire

alphaalpha Posts: 2Questions: 0Answers: 0
edited September 2011 in DataTables 1.8
Hi my friends,

First, thanks Allan for great js library.

I got a small problem with the code piece below, I hope to get your help!

[code]
$(document).ready(function() {
/* Add a click handler to the rows - this could be used as a callback */
$("#resultTable tbody").click(function(event) {
//remove for test
//change background color for selected
$(oTable.fnSettings().aoData).each(function() {
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
//remove for test
///error here: click second times to start effect
$("#resultTable tbody tr").click(function(event) {
var aPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(aPos);
gIDNumber = aData[0];
});

});

/* Init the table */
oTable = $('#resultTable').dataTable();
});
[/code]

After data is added into the table, first click on the table do nothing (can't get gIDNumber = aData[0]) but the second click on table everything is fine.

If I remove the code between "//remove for test", the first click on table is working perfect.

Now, how can I do both things above: highlight the selected row and also get the gIDNumber

Cheers,

Replies

  • GregPGregP Posts: 487Questions: 8Answers: 0
    edited September 2011
    I can't help wondering if part of it is a timing issue. .click() will only bind to elements available at the time it is called; when you remove the one chunk of code it might work just because the timing works out better (the remove/add is a relatively slow process).

    That's just a guess... my head doesn't always wrap around JS timing issues very well.

    One thing I know for sure: when I switched to using .delegate() instead of .click() for events that are fired from a DataTable, 99% of my problems cleared up. This is because .delegate() is like a "promise" to bind events to elements even if they're not in the DOM yet.

    I'd have to look at your document to know for sure I've selected the write elements to create the binding, but it works something like this:

    [code]
    $("#resultTable").delegate("tbody", "click", function(event) {
    // the code that WAS in the .click() function
    });
    [/code]

    If those selectors are not quite right, adjust accordingly with the following: the jQuery object being created (ie. the first selector) is any parent element that you can expect to never get destroyed. It could even be "body" if you need it to be, but the closest non-destroyed parent is a better choice. The second selector (inside the delegate function) is the element that the click is bound to.

    In the above example, the translation is: "resultTable will listen for clicks on any of its tbody elements".
  • alphaalpha Posts: 2Questions: 0Answers: 0
    Thanks GregP,

    I'm lucky to do as following code and it's working perfect:

    [code]$(document).ready(function() {

    $("#resultTable tbody").click(function(event) {

    $(oTable.fnSettings().aoData).each(function() {
    $(this.nTr).removeClass('row_selected');
    });
    $(event.target.parentNode).addClass('row_selected');

    });

    $("#resultTable tbody tr").live('click', function(event) {
    var aPos = oTable.fnGetPosition(this);
    var aData = oTable.fnGetData(aPos);
    gIDNumber = aData[0];

    });

    oTable = $('#resultTable').dataTable();
    });[/code]
  • GregPGregP Posts: 487Questions: 8Answers: 0
    Good stuff. I usually recommend .delegate instead of .live; but that's taking other people's word for the performance benefit (apparently .live() is not very good for performance, but as I also often say, no need to solve a problem you're not having).

    If you did decide to switch to .delegate(), it's just a minor syntax change. Where you currently have a .live() you would have this instead:

    [code]
    $('#resultTable').delegate('tr', 'click', function(event) { ... });
    [/code]

    Should function exactly the same as the .live() binding except now #resultTable is the listener instead of the document.
This discussion has been closed.