cell().data( set ) vs. row().data( d )

cell().data( set ) vs. row().data( d )

Karl53Karl53 Posts: 72Questions: 29Answers: 0
edited March 2015 in DataTables 1.10

Using DataTables 1.10.5, Data source is a JavaScript array of objects, var myData.

I'm trying to get my head around the DataTables data model.

A. This construct, updates the table display but it does not update the array, myData.

    var obj = {item1 : "This", item2 : "does not", item3 : "update the", item4 : "array."};
        table.row(1).data(obj);

B. While this construct updates both the table display and myData.

        var cell = table.cell(4,1);
        cell.data('Big Coffee Maker 4');

C. And, of course, this construct updates both the data in the array and refreshes the display:

        myData[2].item1 = 'This';
        myData[2].item2 = 'updates';
        myData[2].item3 = 'the';
        myData[2].item4 = 'array';
        table.rows().invalidate().draw();

1. What's the difference between cell().data( set ) and row().data( d )? Is the above behavior expected?

2. row(n).data( d ) always seems to write to the DataTable row n in display order, regardless of the modifier. What's the best practice or how do I map back to the array?

3. Further, and related to #2, myData gets programmatically sorted (while DataTable, as mentioned is unordered). After myData is sorted this call table.rows().invalidate().draw(); does not cause DataTable to display the data in the new sorted order. My interpretation of invalidate() is, it should.

4. With C, before myData is sorted the 3rd row of the table is updated (zero based array). But after the sort, the 8th row of the table is updated. So rows().invalidate().draw() does not change the display per the sort but I have to write to the array in such a way as to consider the impact of the sort().

5. I guess a bottom line question would be, given all the ways there is to manipulate data, 1is there one approach that is better than another? And given that the source data's order has to change, what's the best way to keep DataTables (both display and Data()) in sync with it. That is, what should I be using for an index to myData from DataTables?

Thank you.

This question has accepted answers - jump to:

Answers

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

    Hi,

    Excellent set of questions - thanks! So, the key thing to understand here is that DataTables retains the object references, but not the array. So when you update myData DataTables doesn't know anything about that since it has effectively thrown that array away and used its own for data storage.

    But when you update the objects in it, those objects are still referenced by myData (and else where in DataTables since you can have multiple references to a single object in Javascript) hence you see the changes.

    In short, updates to myData have no effect, but updates to the objects it contains does!

    Conversely, to explain why row().data() as a setter doesn't effect myData or the object in it, the data object passed in replaces DataTables referenced object. So it no longer has a reference to the object for that row in myData. As I noted, DataTables has its own array of data (actually it is an array of objects and the data for each row is a property of each object, so it isn't as simple as myData) so it stores the reference to the new object.

    Now, if you want to update the original object what you could do is:

    $.extend( table.row( ... ).data(), newData );
    table.row( ... ).invalidate();
    

    However, you must keep in mind that deleting entries and adding new ones to myData will have no effect. The DataTables API must be used for that.

    In general I would suggest that you forget about myData once you have passed it into DataTables. I do want to make updates so that DataTables will be able to retain it, but I suspect that is going to be rather complex!

    Could you explain a little about what you are trying to achieve and perhaps I can help suggest how it might be done in DataTables.

    Regards,
    Allan

  • Karl53Karl53 Posts: 72Questions: 29Answers: 0
    edited March 2015

    Allan, thanks a lot. That clears up some things for me. This is the key I had not understood:

    DataTables retains the object references, but not the array

    As you suggest, I'll try to explain a bit about what I'm doing, but first, a few more, hopefully quick questions.

    1. Given that myData array is thrown away and that I can populate DataTables with row.add() (or rows.add()), do I need myData? I assume not. I ask because I don't want to initialize DataTable({"data": null}) and get bitten later on because a data source is required under the hood.

    2. The app gets 100% of the data for DataTables from either user input or programmatically (JavaScript) generated data based on rules. Many rules depend upon the physical display location of a row (and the row is frequently not selected).

    If I use DataTable ordering option how do I read from and write to say the physical display location row 3, column 1?

    For me, these 4 statements return the same value:

        console.log(table.cell(2, 0, { order: 'applied' }).data());
        console.log(table.cell(2, 0, { order: 'index' }).data());
        console.log(table.cell(2, 0, { order: 'original' }).data());
        console.log(table.cell(2, 0, { order: 'current' }).data());
    

    and these write to the same display location which isn't the physical row 3 due to the applied ordering:

        table.cell(2,0, { order: 'applied' }).data("Hello");
        table.cell(2,0, { order: 'index' }).data("Hello");
        table.cell(2,0, { order: 'original' }).data("Hello");
        table.cell(2,0, { order: 'current' }).data("Hello");
    

    2b. And I guess an implied question, since all the above produce the same results, what is the modifier parameter for or how is it used?

    3. The various way to call data() seem to return values. That is the result is static. What is return is not a reference to the data. Am I understanding correctly?

    Thanks.

    Two small notes about the DataTables documentation:

    A. Here:

    http://datatables.net/reference/type/cell-selector

    • objectJS - DataTables cell indexes (row and column properties)

    The option isn't actually a JavaScript object is it? Rather the option should be 2 number parameters.

    B. Here:

    http://datatables.net/reference/type/selector-modifier

    Original is an alias of itself?

    original - Alias of original for backwards compatibility.

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

    1) Given that myData array is thrown away and that I can populate DataTables with row.add() (or rows.add()), do I need myData? I assume not.

    I would say not. If you are using rows.add() just have an empty table - no need to populate it if it doesn't need to be at initialisation!

    2) If I use DataTable ordering option how do I read from and write to say the physical display location row 3, column 1?

    The reason the statements you have aren't working is that the selectors (the first two parameters) are indexes. The third parameter effects only the return data structure - not what is actually selected. You need to modify the selectors:

    console.log(table.cell(':eq(2)', 0).data());
    

    Of course if you are using a click event on the cell you want to get data for you could just use table.cell(this).data() since the cell selector can be a node.

    3) The various way to call data() seem to return values. That is the result is static. What is return is not a reference to the data. Am I understanding correctly?

    Its a bit like the situation with data and myData discussed above. The array is not a reference to anything, it is just a container, but the objects contained in it are. So the array is static, yes. The objects inside are not.

    A) The option isn't actually a JavaScript object is it?

    Yes, you can use { row: y, column: x } as a cell-selector. The key thing here is that cell() can take a dt-type cell-selector, or both adt-type row-selectoranddt-type column-selector` which is what you describe - two indexes.

    B) Original is an alias of itself?

    Doh - its an alias of index. Fix committed - thanks!

    Allan

This discussion has been closed.