Accessing cell data and HTML elements

Accessing cell data and HTML elements

MV10MV10 Posts: 12Questions: 2Answers: 0

I'm having difficulty finding the right syntax to get to the underlying data for a cell and the actual <TD> element for the cell. Briefly, the first column of the table contains checkboxes. The data is JSON and each object in the array has a "manuallychecked" key/value pair which indicates whether the row was checked one-by-one. The user can also toggle all checkboxes on/off, and when they're toggled off, the idea is that we restore the manually-checked states.

I am trying to loop through each row and check the manuallychecked flag in the underlying data, and then access the checkbox element in the <TD> to set the checked property. I think I'm pretty close:

function gridToggle() {

    // if true, ignore manuallychecked; if false, refer to manuallychecked
    allChecked = !allChecked;

    // grab one of these because we use it multiple times
    var api = summaryGrid.api();

    // loop through each row
    api.rows().each(function(val,idx) {

        // clearly something goes wrong
        // i have 16 rows but i get to this point just once; idx = 0
        // but cel appears to be a valid DT cell() object
        var cel = api.cell(idx,0);

        // cel.data().manuallychecked is "undefined" instead of true/false
        var chk = allChecked || cel.data().manuallychecked;

        // this doesn't throw errors but nothing happens; i suspect node() isn't right?
        $(cell.node()).find("input:checkbox").prop("checked", chk);
    });
}

This question has an accepted answers - jump to answer

Answers

  • MV10MV10 Posts: 12Questions: 2Answers: 0

    I took a different approach trying to do it more like the examples, all in one big shot, and think I got a little closer, but the data().manuallychecked part throws an error... hopefully you can follow what I'm up to here:

    var api = summaryGrid.api();
    
    $(api
       .column(0)
       .nodes()
    ).find("input:checkbox")
    .prop("checked", allChecked ||
                               api.cell(this).data().manuallychecked);
    
    

    Also, the comment "preview" button doesn't work (at least, not on the latest Firefox, haven't tried other browsers)

  • MV10MV10 Posts: 12Questions: 2Answers: 0

    Hmm, thinking cell().data() refers to the data for ONLY that cell, so I tried this:

    api.cell(this).row().data().manuallychecked

    thinking it would let me step back to the row-level data. But it throws this error, which sounds suspiciously like a bug, maybe. (I'm running the 1.10.1-dev release, by the way.)

    Unable to get value of the property 'aData': object is null or undefined.

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Hi,

    I think what you want is indeed the row().data() method - but without the cell() part that you had. The reason being is that the row().data() method will get the original data object for the whole row - whereas the cell().data() method will indeed, as you say, get the data for that cell only.

    In the code above is this the td element? If so use api.row( this.parentNode ).data().

    On other thing worth pointing out about this line:

    api.rows().each(function(val,idx) {

    Likely you will want to use the eq() method - i.e.:

    api.rows().eq(0).each( function (val, dix) {
    

    The reason for this is that the DataTables API can operate on multiple tables, so rows() returns a 2D array - one item in the top array for each table in the API's context.

    Regards,
    Allan

  • MV10MV10 Posts: 12Questions: 2Answers: 0

    Thanks. Yes this refers to the <td> node, but the row(this.parentNode) version still throws the aData error I mentioned.

    Thanks also for the reply on that other thing in email, I'll get to work on that today!

  • MV10MV10 Posts: 12Questions: 2Answers: 0
    edited July 2014

    Here is a bare-bones jsfiddle illustrating the basic concept and the error. I used the CDN so this references DT 1.10.0.

    http://jsfiddle.net/MV10/DRb2B/2/

    Click "toggle" twice to see the error. The first run short-circuits because checkAll is true, but on the second run checkAll is false, so it goes on to evaluate the attempt to read the data.

    In Firefox the error is "TypeError: ctx[0].aoData[this[0]] is undefined"

    (The error message is different because I wrote the jsfiddle from my personal machine using Firefox 30, whereas the earlier posts referenced results from my work machine which is (sadly) limited to IE9.)

    Tried another trick, too, just to be absolutely sure the <tr> was being passed to row() and got the same result:

    api.row( $(this).parents("tr")[0] ).data().manuallychecked

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Answer ✓

    Thanks for the link to the JSFiddle. In the toggleAll function, this is not the td element, but rather window (since you are using a DOM0 event). Even if you had been using jQuery events, it would still only point to the button node. I think in this case a loop is going to be unavoidable.

    Something like:

        var api = summaryGrid.api();
        $(api.column(0).nodes())
            .find("input:checkbox").each( function () {
                $(this).prop(
                    'checked',
                    allChecked || api.row( $(this).closest('tr') ).data().manuallychecked
                );
            } );
    

    So you loop over the input elements, check if they are manually checked or not, and perform the action.

    Updated fiddle: http://jsfiddle.net/DRb2B/8/

    Allan

  • MV10MV10 Posts: 12Questions: 2Answers: 0

    Oh wow. I feel stupid. Thanks!

This discussion has been closed.