statesave type option for child row state - class of open row

statesave type option for child row state - class of open row

crush123crush123 Posts: 417Questions: 126Answers: 18
edited February 2017 in DataTables 1.10

i have been modifying a datatable to add a child row - as the number of fields displayed was making the row a bit cluttered - much better now !

Most elements of the child row are links to related pages, each with a back button to my main page.

what i would like to do is retain the child row in its open state when going back to the page.

using information in another thread

https://datatables.net//forums/discussion/comment/88178/#Comment_88178

I can store the indexes of the open child rows in an array, and use localStorage to retain the values

on initComplete i am using the values stored in localstorage to show the child rows, but i cannot get the class of the open row to display as 'shown'

code to store open rows...

        var openTableRows = JSON.parse(localStorage.getItem('openRows'));

$('#example 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);
            localStorage.setItem('openRows', JSON.stringify(openTableRows));
            //console.log(JSON.parse(localStorage.getItem('openRows')));

    }
    else {
        // Open this row
        row.child( format(row.data()) ).show();
        tr.addClass('shown');

            rowIndex = row[0][0];
            openTableRows.push(rowIndex);
            localStorage.setItem('openRows', JSON.stringify(openTableRows));
            //console.log(JSON.parse(localStorage.getItem('openRows')));
    }
} );

code to re-open previously open rows...

initComplete: function ( settings, json ) {

        var table = $('#example').DataTable();
        table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
        openRows = JSON.parse(localStorage.getItem('openRows'));
        openRows.forEach(function(entry) {
        var tr = entry;
        var row = table.row(tr);
        row.child(format(row.data())).show();
        })
        })

        }

if I add tr.addClass('shown'); to the block above, i get error tr.addClass is not a function

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin

    I wonder if it might be easier to try trigger the click event that has been subscribed? You could do something like:

    $( 'td.details-content', row.node() ).click();
    

    Then you don't have duplicate code anywhere. If you need to update the child code at all, then the above activation would use that updated code.

    Allan

  • crush123crush123 Posts: 417Questions: 126Answers: 18

    sorry Allan, I am punching above my weight as it is.

    I don't understand your answer.

    Is this a different approach or a modification of my existing one ?

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin

    Modification. Basically instead of called row().child() etc in the initComplete callback just call the click event handler.

    Add my line above inside your forEach instead of the row().child() call.

    Allan

  • crush123crush123 Posts: 417Questions: 126Answers: 18

    hmm, that doesnt seem to work.

    i tried changing td.details-content to td.details-control,

    something happens, but not what I want

    i will set up a test page with a link when i get a chance

    Thanks Allan

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin

    Sounds good - thanks.

    Allan

  • crush123crush123 Posts: 417Questions: 126Answers: 18

    i have uploaded a test page to http://test.forthwebsolutions.com/event_results_3.php and left the console log messages intact.

    the code which adds and removes the open rows in an array seems to work fine.

    the original line 322 will re-open the child row on page load, but not show the 'opened' image

    your suggestion is on line 323 - which calls the click event and re-closes the open child rows

    hope you can help me work this out. - thanks

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin

    Its happening twice :smile:. The row is actually opening, but because of a duplicate in the openTableRows array it is actually then being immediately closed again!

    Have a look at the attached screenshot - you can see I've got a break on the click trigger. I've let it run once, and the row is open. Now its running again (in the console you will be able to see [5, 5]) and a second click on the row is going to close it.

    That duplicate in the array is what is causing you issues now.

    Allan

  • crush123crush123 Posts: 417Questions: 126Answers: 18

    the only point at which a rowindex is added to the array is openTableRows.push(rowIndex);

    and as you correctly pointed out, the page was adding this a second time when the click event was called.

    i modified this code, so that now i check the array to see if the index exists, and only add it to the array if it doesn't exist already.

    this stops duplicate entries into the array, but the loop still appears to run twice, and re-hides the 'open' row

    i tried adding a break point on line 418 and it shows this quite well

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin
    Answer ✓

    Its still happening twice, open then close. I think this is because caused by the fact that there is a forEach inside the every. I think the rows().every() call is redundant.

    Could you just comment out the line for rows().every() and is corresponding closing line?

    The rest of it looks okay since the entry in the openTableRows is the row index. So you could end up with just:

            if ($.isEmptyObject(openTableRows)==false) {
                openTableRows.forEach(function(entry) {
                    $( 'td.details-control', table.row( entry ).node() ).click();
                });
            }
    

    Allan

  • crush123crush123 Posts: 417Questions: 126Answers: 18

    awesome !

    thanks Allan, I appreciate your help

This discussion has been closed.