Add child rows visibility status to state save params

Add child rows visibility status to state save params

Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

Having read around the forum I think I am right in saying that at present it is not possible to add the status of a child row, i.e. open or closed, to the state params?

Currently I use this method to reload the table,

var table = $('#cms_module_system_bookings').DataTable();
table.ajax.reload( null, false );

So my question is can another option be used to reload server side table data which does maintain the status of any open child rows? If not, is there any conceivable way a solution could be developed to maintain the status of the child rows?

Many thanks

Answers

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

    I am right in saying that at present it is not possible to add the status of a child row, i.e. open or closed, to the state params?

    That is correct. Although you could use the stateSaveParams option to add that information if you wanted.

    So my question is can another option be used to reload server side table data which does maintain the status of any open child rows?

    Before you make the Ajax call, loop over all the rows and detect which ones are "open". Save that information (it should be a unique id from the data or similar - obviously the DOM node is no use since it will be destroyed). Then in the ajax.reload() callback loop over the rows again and open those which have been found to be open.

    Not particularly elegant - but it will work nicely.

    Allan

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Hi Allan,

    I am using this code to store the id of each open child row in a cookie.

    $('#cms_module_system_bookings tbody').on('click', 'td.details-control', function() {
                var tr = $(this).closest('tr');
                var row = table.row(tr);
                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    tr.removeClass('shown');
                    rowIndex = row[0][0];
                    var idx = openTableRows.indexOf(rowIndex);
                    openTableRows.splice(idx, 1);
                    Cookies("openRows", openTableRows);
            } else {
                    // Open this row
                    row.child(format(row.data())).show();
                    tr.addClass('shown');
                    rowIndex = row[0][0];
                    if (openTableRows.indexOf(rowIndex) < 0)
                    openTableRows.push(rowIndex); // push the row index into the openrows array
                    Cookies("openRows", openTableRows);             
            }
            });
    

    Which works as I can see a comma separated list of values in the resources cookies log.

    I added the following code to my ajax.reload function but it fails.

        function reload() {
            var table = $('#cms_module_system_bookings').DataTable();
            table.ajax.reload(function(json) {
                var openRows = Cookies("openRows");
                if (!openRows)
                return;
                openTableRows = eval(openRows);
                $(table.rows().nodes()).each(function(idx, tr) {
                    if (openTableRows.indexOf(idx) >= 0) {
                        row = table.row(tr);
                        alert(openTableRows.indexOf(idx));
                        row.child(formatChildTable(tr, row.data())).show();
                        $(tr).addClass("shown");
                    }
                });
            });
        }
    

    I get this error in the console Uncaught ReferenceError: formatChildTable is not defined. But I also think I am not retrieving any values for each row index from the cookie correctly as when I do an alert on alert(openTableRows.indexOf(idx)); I get the value -1.

    I am obviously doing quite a few things wrong! Can you point me in the right direction?

    Thanks

    Chris

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

    Do you really need to store it in a cookie? You'd only do that for a full page reload, and in this case yo are using ajax.reload() so no cookie is needed.

    I'd suggest you use rows().every() to loop over the rows before you make the Ajax request and get the open rows. That should be the starting point.

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Hi Allan. Okay, that makes sense. If I am just using the ajax.reload function can I store the row ids in a standard javascript var or will that be destroyed when the reload function runs?

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

    Yes you can store it in a var.

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    I think I am getting there, maybe!

    function reload() {
    var openRows = [];
    var table = $('#cms_module_system_bookings').DataTable();
    table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
    var tr = rowIdx;
    var row = table.row(tr);
    if (row.child.isShown()) {
    openRows.push(rowIdx);
    }
    });
    table.ajax.reload( null, false );
    openRows.forEach(function(entry) {
        var tr = entry;
        var row = table.row(tr);
        if (row.child.isShown()) {
            row.child(format(row.data())).show();
            tr.addClass('shown');
        }
    });
    }
    

    I save all the open row ids correctly and loop through them again after my ajax.reload but it fails when I get to

    row.child(format(row.data())).show();
    tr.addClass('shown');
    

    I see the error message "Uncaught ReferenceError: format is not defined". Where and how do I define "format"?

    Thanks

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

    Use the callback function of the ajax.reload() method as I mentioned above. Otherwise you are just running the forEach loop before the reload has actually happened (Ajax is async remember).

    I see the error message "Uncaught ReferenceError: format is not defined". Where and how do I define "format"?

    Well its a function that you are calling above (format(row.data())). So I guess you've copied and pasted that code from my example without including the format function - but that is just a demonstration.

    Given that you are opening the child rows somewhere else already, I'd suggest you use exactly the same approach as you have there.

    Allan

  • slashkillslashkill Posts: 1Questions: 0Answers: 0

    Very usefull thank you allan and Restful web service :)

This discussion has been closed.