Saving multiple panel's collapsed state using cookies with $.cookie()

前端 未结 5 1039
野性不改
野性不改 2021-02-01 19:12

I\'m trying to determine how I might save a collapsible panel\'s collapsed state using $.cookie.

This question has been helpful so far, but still missing the end soluti

相关标签:
5条回答
  • 2021-02-01 19:32

    You should save the active panels in an array and store it in a cookie instead saving only 1 id at a time.

    Your JS should be like this:

    var activePanels = []; // array for the active panels
    $(".panel .panel-collapse").on('shown.bs.collapse', function ()
    {   
        var active = $(this).attr('id');
        activePanels.push(active); // store the active panel id into the array
        $.cookie('activePanelGroup', activePanels); // add array to the cookie
        console.log($.cookie('activePanelGroup')); // display current active panels stored in the cookie
    });
    
    $(".panel .panel-collapse").on('hidden.bs.collapse', function ()
    {
        var selectedPanel = $(this).attr('id');
        var index = activePanels.indexOf(selectedPanel);
        if (index > -1) // if id exists on the active panels array
          activePanels.splice(index, 1); // remove it on the active panels array
        $.cookie('activePanelGroup', activePanels); // add the updated active panels array to remove the old one
        console.log($.cookie('activePanelGroup')); // display current active panels stored in the cookie
    });
    
    var aPanels = $.cookie('activePanelGroup');  // retrieve all active panels 
    
    if (aPanels != null)
    {   
        //remove default collapse settings
        $(".panel .panel-collapse").removeClass('in');
        // put all active ids to array
        var arr = aPanels.split(",");
        // loop on each active panels
        $.each( arr, function( key, value ) {
          //show the account_last visible group
          $("#" + value).addClass("in");
    
          // store again the selected panels so it won't get reset on reload
          activePanels.push(value);
          $.cookie('activePanelGroup', activePanels);
        });
    }
    

    Fiddle

    0 讨论(0)
  • 2021-02-01 19:37

    This will create a cookie for every panel when it's shown and remove the cookie when the panel is hidden.

    $(".panel .panel-collapse").on('shown.bs.collapse', function ()
    {
        var active = $(this).attr('id');
        $.cookie(active, "1");
    });
    
    $(".panel .panel-collapse").on('hidden.bs.collapse', function ()
    {
        var active = $(this).attr('id');
        $.removeCookie(active);
    });
    

    So, when loading the document, we check every cookie and expand the panel.

    $(document.ready(function(){
        var panels=$.cookie(); //get all cookies
        for (var panel in panels){ //<-- panel is the name of the cookie
            if ($("#"+panel).hasClass('panel-collapse')) // check if this is a panel
            {
                $("#"+panel).collapse("show");
            }
        }    
    });
    

    USING LOCALSTORAGE

    However, as someone suggested, using localStorage may be a better option. localStorage is great for this.

    $(".panel .panel-collapse").on('shown.bs.collapse', function ()
    {
        var active = $(this).attr('id');
        var panels= localStorage.panels === undefined ? new Array() : JSON.parse(localStorage.panels);
        if ($.inArray(active,panels)==-1) //check that the element is not in the array
            panels.push(active);
        localStorage.panels=JSON.stringify(panels);
    });
    
    $(".panel .panel-collapse").on('hidden.bs.collapse', function ()
    {
        var active = $(this).attr('id');
        var panels= localStorage.panels === undefined ? new Array() : JSON.parse(localStorage.panels);
        var elementIndex=$.inArray(active,panels);
        if (elementIndex!==-1) //check the array
        {
            panels.splice(elementIndex,1); //remove item from array        
        }
        localStorage.panels=JSON.stringify(panels); //save array on localStorage
    });
    

    When you load the page, get the values of localStorage and show the panels.

    $(document.ready(function(){
        var panels=localStorage.panels === undefined ? new Array() : JSON.parse(localStorage.panels); //get all panels
        for (var i in panels){ //<-- panel is the name of the cookie
            if ($("#"+panels[i]).hasClass('panel-collapse')) // check if this is a panel
            {
                $("#"+panels[i]).collapse("show");
            }
        }  
    });
    

    EDIT: See it working: FIDDLE

    0 讨论(0)
  • 2021-02-01 19:38

    You can have the settings in a single cookie (i.e. comma separated) and update it on open-close.

    openPanels = $.cookie('activePanelGroup').split(",");
    

    See your edited JsFiddle example working here.

    EDIT

    I agree with Chris. I find it a more elegant solution to have all values stored in a single cookie, however, we should keep in mind the single cookie size limitations. (This varies based on browser).

    0 讨论(0)
  • 2021-02-01 19:48

    I'd rather use localStorage than cookies.

    You just need to create a variable on local storage for each panel associated to it's id, where you store the state of the panel.

    When loading the page, just loop all panel classed objects checking it's associated variable in local storage and applying appropiate classes depending on the value.

    0 讨论(0)
  • 2021-02-01 19:49

    <!-- when you have multiple levels of child-sections like this below - to hide/collapse or show and restore again -->
    <!--here's how I kept track of their id's - ps. I have since removed the multiple -->
    <!--tables but, it looked like this when I put this answer in -->
    
        <div class="panel-group" id="accordion">
            <div class="panel panel-default">
                <div class="panel-heading">
                </div>
                <div class="panel-body">
    <!--TABLE 1-->
                    <table class="table table-condensed" style="border-collapse: collapse;">
                        <tbody class="component-grp">
                            <tr data-toggle="collapse" data-parent="#accordion" data-target="#compogrp@x" class="accordion-toggle">
                                <td colspan="10">
                                    <div class="">
                                    </div>
                                </td>
                            </tr>
                            <tr>
                                <td class="hiddenRow">
                                    <div class="accordian-body panel-collapse collapse" id="compogrp@x">
    <!--TABLE 2-->
                                        <table class="table table-striped">
                                            <thead>
                                                <tr class="header">
                                                    <th></th>
                                                    <th>Position</th>
                                                    <th>shape</th>
    
                                                </tr>
                                            </thead>
                                            <tbody class="component-row">
                                                <tr data-toggle="collapse" data-target="#comp-@x" class="accordion-toggle collapsed">
                                                    <td>
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td colspan="10" class="hiddenRow">                                                
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
    
            </div>
    
        </div>

    Let me throw in an additional alternative: if you have customized the bootstrap panel example like me and ended up with multiple nesting for your accordion,then assuming you have unique ids for your collapsing & expanding element (the panel that expands or collapses), you can trap the (rely on) click event to get the id of the panel collapsing/expanding no matter how deep it's located in the nesting.

    I customized the examples in stackoverflow to achieve this; basically it gets the id of the expanded panel on click event, creates a cookie with the id as name (var temp) which will be used to remove it later if panel is collapsed. Then loop through cookie on page refresh (or etc.) to restore the accordion state. I must mention that cookies are not recommended for this type of spec. Thus, you can change the code to use localStorage or Javascript array. Hope this helps someone.

        $(document).on('shown.bs.collapse', function (e) {
               //whenever and wherever a panel is shown on any level of the  nesting, save the id in a cookie
                var active = $(e.target).attr('id')
               var temp = active;
                $.cookie(temp, active);
                console.log("panel expanded: ");
            });
    
            $(document).on('hidden.bs.collapse', function (e) {
                var temp = $(e.target).attr('id')
               //whenever and wherever a panel is collapsed on any level of the  nesting, remove the corresponding cookie
                $.removeCookie(temp);
                console.log("panel collapsed: ");
    
            });
    
            function restoreActiveAccordionGroup() {
                 var last = [];
                 last = $.cookie();
                if (last) {
    
                    //remove default collapse settings from all panels
                    $("#accordion").removeClass('in');
                    for (var i in last) {
                    //restore the last visible panel group in all nested levels
                    $("#" + i).addClass("in");
                    }
    
                }
            }
    
    0 讨论(0)
提交回复
热议问题