Best way to access a td value

Best way to access a td value

bgardnerbgardner Posts: 17Questions: 0Answers: 0
edited November 2009 in General
I'm new to DataTables, but I like what I see so far. I am having a problem with one table that I have created with it. When the user selects a row in the table, I'm using Ajax to open up some details for the given row. I do two things when they click a row, I highlight that row with a little CSS, and then get an Id from that row, and post an Ajax call to populate some additional information elsewhere on the page.

The problem I have is that this only works on the first page of output from the table. If I paginate to a later page, I get neither color not posting. Here is my (rather poor) code for this event. Can someone tell me if there is a reason this should only work on the first page of output? I am open to any other comments as well.

[code]
$("#request-table tbody tr").click(function(event) {
$(oTable.fnSettings().aoData).each(function (){
$(this.nTr).css('background-color','#FFFFFF');
});

$(event.target).parent().css('background-color','#CC99B3');

var aPos = oTable.fnGetPosition( this );
var aData = oTable.fnGetData( aPos );
var requestId = aData[0];

$.post("listDetails.action",
{ acsrRequestId: requestId } ,
function(ltext, lstatus){
$('#info-panel').html(ltext);
}
);
});
[/code]

Replies

  • izzy6150izzy6150 Posts: 49Questions: 0Answers: 0
    Hi bgardner,

    The reason this is not working when paging is that the table is being redrawn and thus loosing your click method which is currently only attached to your initial data.

    you could try something like the following which might work:
    [code]
    $(document).ready(function() {
    $('#example').dataTable( {
    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
    /* Add your click event to the row */
    nRow.click = function() {
    $(this).css('background-color','#FFFFFF');
    $(this).parent().css('background-color','#CC99B3');

    var requestId = aData[0];
    $.post("listDetails.action", { acsrRequestId: requestId }, function(ltext, lstatus){
    $('#info-panel').html(ltext);
    });
    }

    return nRow;
    }
    } );
    } );
    [/code]
    Not sure if that is correct but it might point you in the right direction.

    Regards,
    Izzy
  • bgardnerbgardner Posts: 17Questions: 0Answers: 0
    Thanks for the quick response, Izzy. I'll try it and report back here.

    Brian
  • bgardnerbgardner Posts: 17Questions: 0Answers: 0
    OK, I'm back from the long weekend. Here is what I changed it to. The post never fires, so this is still not working.

    [code]
    oTable = $('#request-table').dataTable({
    "bJQueryUI": true,
    "bAutoWidth": false,
    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
    /* Add your click event to the row */
    nRow.click = function() {
    var requestId = aData[0];
    $.post("listDetails.action", { acsrRequestId: requestId }, function(ltext, lstatus){
    $('#info-panel').html(ltext);
    });
    }
    return nRow;
    }
    });
    [/code]

    This looks like it should work, but nothing happens at all, no errors, and no post. Any other ideas?

    Brian
  • allanallan Posts: 61,822Questions: 1Answers: 10,127 Site admin
    Hi guys,

    I get a little nervous with using fnRowCallback for assigning events :-). The main problem I have with them (isn't actually an issue here due to a different problem...) is that it will typically leak an event handler - what I mean by this is that each time the row is drawn it would add the event handler again, thus allowing scope for some nasty problems.

    Now this isn't actually an issue here since nRow.click is the DOM0 style of dealing with events, so in this case it's actually just going to assign the click function on each row draw. Okay, but not optimal, and not taking advantage of jQuery's event handling. As such it is worth considering using $(nRow).click( function (e) {...} ); - but then you run into the multiple events issue I mentioned before...

    So, since the table you are using is a nice plain HTML table with no server-side processing or Ajax (from your code above), you have two options:

    1. Add the events before you initialise DataTables: http://datatables.net/examples/advanced_init/events_pre_init.html

    2. Add the events after you initialise DataTables: http://datatables.net/examples/advanced_init/events_post_init.html

    There is a little code example in each of those which will hopefully point you in the right direction. If not, give us a shout here.

    Regards,
    Allan
  • bgardnerbgardner Posts: 17Questions: 0Answers: 0
    Allan,

    Maybe if I describe what it is I'm trying to do, you can point me in the direction of a better way to handle this.

    1. I have a datatable. It can have many rows (more than a screen-worth)
    2. When a user selects a row in the table (at any area in the row) an Ajax call is made to populate a "more details" section on the page.
    3. I would prefer to highlight the currently selected row (which also means that a previously highlighted row is now unhighlighted.

    This was working fine for me with the code in the original post, but only on the first page that is displayed. Is there a better way to do what I'm attempting?

    I appreciate your help.
    Brian
  • allanallan Posts: 61,822Questions: 1Answers: 10,127 Site admin
    Hi Brian,

    Try something like this:

    [code]
    var oTable;
    $(document).ready( function () {
    $("#request-table tbody tr").click(function(event) {
    $(oTable.fnSettings().aoData).each(function (){
    $(this.nTr).css('background-color','#FFFFFF');
    });

    $(event.target).parent().css('background-color','#CC99B3');

    var aPos = oTable.fnGetPosition( this );
    var aData = oTable.fnGetData( aPos );
    var requestId = aData[0];

    $.post("listDetails.action",
    { acsrRequestId: requestId } ,
    function(ltext, lstatus){
    $('#info-panel').html(ltext);
    }
    );
    });

    oTable = $('#request-table').dataTable({
    "bJQueryUI": true,
    "bAutoWidth": false
    });
    } );
    [/code]
    That's a combination of the code that you've posted. Does that work for you?

    Regards,
    Allan
  • bgardnerbgardner Posts: 17Questions: 0Answers: 0
    Allan,

    That works very well! Now I just need to read through it with the docs in front of me so I can understand how it works. I appreciate your help very much.

    Brian
  • allanallan Posts: 61,822Questions: 1Answers: 10,127 Site admin
    edited November 2009
    Hi Brian,

    Good stuff - good to hear that works :-)

    Here is a very quick explanation... If you remove the four lines which are using for DataTables initialisation there, your table will still work for the "more details" functionality. The events are all assigned to the rows - great.

    So then you initialise DataTables, but that doesn't destroy what has been done to the table already - all that information is retained. All DataTables does is shunt the DOM elements about a bit for the display (paging, sorting, filtering etc).

    The alternative explanation is that it's dark magic... Pick which one you prefer :-)

    Regards,
    Allan
This discussion has been closed.