How can I reset column visibility to what it would be without the save state

How can I reset column visibility to what it would be without the save state

CharleyCharley Posts: 66Questions: 17Answers: 0

Link to test case:
https://stackoverflow.com/questions/31437320/reset-column-reorder-and-colvis-in-one-button
https://datatables.net/extensions/colvis/api

Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:
I tried the suggestion from stack overflow, but jQuery.fn.dataTable.ColVis.fnRebuild is undefined. Issue in 10.16, 10.18 (current deployed on site) and 10.24

colvis restore button restores to what was on the page for the page reset, which isn't what I'm looking for...

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited April 2021

    Not sure I understand fully but I do have a very similar requirement, I guess. I need to do some manipulations to certain columns that only work if the columns are visible at the time of the manipulations. So what I do is
    - I save the loaded state regarding column visibility if it exists
    - I make all columns visible (you could make visible whichever where visible before loading the state - which could be all or only a selection)
    - I do the manipulations
    - I restore column visibility as per the loaded state so that the user doesn't notice anything (something you might not need, but I don't know)

    Please also check this https://datatables.net/reference/api/state() and its data object.

    initComplete: function () {
        //save the loaded state regarding column visibility
        var colArray = [];
        if ( stateSave ) {
            colArray = ctrTable.state().columns; 
        }
        ctrTable.columns().visible( true );
        var table = this.api();
        $('.filterHead', table.table().header()).each( function (i) {
                    ... do all kinds of things ...
        } ); 
        //restore the loaded state regarding column visibility
        $.each(colArray, function(key, value) {
            if ( ! value.visible ) {
                ctrTable.column(key).visible( false );
            }
        })
    },
    

    You can also manipulate the state before it actually loads:
    https://datatables.net/reference/option/stateLoadParams
    The "data" object that is described in the doc above should be passed into that callback allowing you to manipulate it before it actually loads.

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited April 2021

    Here is some code that would simply set all columns to visible before the state is actually loaded. If you know which columns should be visible without state loading you can modify this individually:

    $('#example').dataTable( {
      "stateSave": true,
      "stateLoadParams": function (settings, data) {
            $.each(data.columns, function(key, value) {
               data.columns(key).visible( true );
            });
        })
      }
    } );
    

    You can also try to delete the columns array from the data object ... But that might cause data tables to crash ...
    The object is described here: https://datatables.net/reference/api/state()

    $('#example').dataTable( {
      "stateSave": true,
      "stateLoadParams": function (settings, data) {
            delete data.columns;
        })
      }
    } );
    
  • CharleyCharley Posts: 66Questions: 17Answers: 0

    unfortunately, just setting everything to visible is not what I'm looking for (doing that is trivial).

    my code is shared between dozens of pages, some with multiple tables per page.

    In one case, the table has 8 columns, only 4 of which are visible by default. I'd particularly like to reset that one back to it's default. Simply setting that to all visible is not ideal by any means.

    I could write it to force it to show correctly for that particular case, but I'd really like a way to make the general case work so I don't have fix dozens of pages individually.

  • CharleyCharley Posts: 66Questions: 17Answers: 0
    edited April 2021

    I'm not looking to change things on page load or when the save state restores... I want it to restore the save state exactly like it was the last time they were on the page.

    I also want the user to be able to reset the table back to it's defaults after having manipulated the table for a bit, clearing searches (both table and column searches) column order, and column visibility.

    I've got all of that working EXCEPT the column visibility.

    I could so something like
    1. alter the table markup to turn off the save state
    2. destroy the table
    3. rebuild the table
    4. alter the table markup to turn on the save state
    5. destroy the table again
    6. rebuild the table.

    that seems like it would be a lot heavier lift than just resetting the column visibility though, and there should be a better way to do it

    I can look at the table markup and reconstruct what the default visibility should be, but that isn't trivial (especially since visiblity can be set on either the header element or in a column definition on the table element)

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited April 2021

    forget my second posting, doesn't work.

    Why don't you just allow the user to delete the entire state? I have a button for my users to do exactly that.

    I'm not looking to change things on page load or when the save state restores... I want it to restore the save state exactly like it was the last time they were on the page.

    For that you don't need to do anything. Just turn "stateSave" on.

    I also want the user to be able to reset the table back to it's defaults after having manipulated the table for a bit, clearing searches (both table and column searches) column order, and column visibility."

    Are you aware of this? https://datatables.net/reference/api/state.clear()

    Just make a little button to allow the user to do the above.

  • CharleyCharley Posts: 66Questions: 17Answers: 0
    edited April 2021

    For that you don't need to do anything. Just turn "stateSave" on.

    save state is already on. The save/restore state part works just fine.

    the problem is that users get themselves into a state where it's not obvious that they've hidden something or have a search that they are oblivious to, or shown too much and now have trouble filter out what's on the page mentally.

    Are you aware of this?

    That was actually my original approach, but reloading the page isn't a great option for a couple reasons
    1. There are multiple datatables on the some pages, so clearing out multiple states would mean multiple page reloads.
    2. Some of the pages aren't lightweight, so reloading the whole page is kind of slow, especially compared to just rebuilding the already loaded data on the page
    3. The pages themselves have other widgets; some, for example, include data entry for something else using the information in the datatable as supporting/reference information. Reloading in those causes means loss of data (whatever the user has typed and not saved).

    I've since switched to having a reset table button, which allows users to reset a specific table in a lightweight way. Like I said, I have all of the resets working except for colvis.

    If there isn't a good way to reset that, I'm probably going to have to do something like

    dt.columns().every( function () {
    var col = this;
    var colHeadElem = jQuery(this.header());
    var vis = (colHeadElem.data("visible") != false)
    col.visible(vis);
    });

    that only picks up columns that data-visible="true/false" and not columns with visibility set in a different way.

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited April 2021
    1. There are multiple datatables on the some pages, so clearing out multiple states would mean multiple page reloads.

    Well, I have a more radical approach to this ... I delete local storage completely, without using the api. Hence: Only one reload.

    onclick="localStorage.clear();"
    

    that's my solution :-)

  • kthorngrenkthorngren Posts: 20,302Questions: 26Answers: 4,769
    Answer ✓

    Try using the settings parameter of the statLoadParams option. I believe that will have the original column settings defined with the Datatables options. You can store that in a global variable and use that variable to reset to the default settings. For example:
    http://live.datatables.net/minexexu/1/edit

    Kevin

  • CharleyCharley Posts: 66Questions: 17Answers: 0

    @rf1234
    while I can admire the simplicity, that has too much of the "throw the baby out with the bathwater.

    and really, I don't want to load some of these pages more than once. I've slapped datatables onto legacy pages because it's a simple way to get a lot of bang for the buck. In many cases, it was to specifically get rid of a legacy UI that sorted/filtered by page loads (which was painfully slow). I'm talking a project that has vestiges of code written specifically for IE4. Whenever I can, I do redesign to optimize to get rid of that sort of problem, but I seldom get enough time to do that sort of thing.

    Kevin's comment looks like a winner... that captures the current state right before the save state is loaded, and then I can restore to that, without having to page load. It should be flexible to work for both data-visible on the TH tags and anything that might be set in the initial config (mostly happens for group columns that are hidden)

    I appreciate all of the feedback

This discussion has been closed.