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 solution.
Any solutions I have found so far have only saved the last rolled down panel so when the page is reloaded the only panel saved is the last one.
What I need is to save all panels that are rolled down rather than just one.
Link to jCookie plugin on Github.
Link to demo on JSFiddle
UPDATE
It has been suggested that LocalStorage is a more appropriate solution to what I am trying to achieve. If you can comment on why and what local storage is that would be much appreciated.
UPDATE 2
because of the suggestion that local storage would be an improvement over using cookies for this problem. The selected answer was based off this. However as mentioned by Robin, there are downsides to using this technique on HTTPS sites.
HTML
<div class="panel panel-default">
<div data-toggle="collapse" data-target="#panel1" class="panel-heading collapsed">
<h4 class="panel-title">
<a> Panel 1 </a>
</h4>
</div>
<div id="panel1" class="panel-collapse collapse">
<div class="panel-body">
</div>
</div>
</div>
<div class="panel panel-default">
<div data-toggle="collapse" data-target="#panel2" class="panel-heading collapsed">
<h4 class="panel-title">
<a> Panel 2 </a>
</h4>
</div>
<div id="panel2" class="panel-collapse collapse">
<div class="panel-body">
</div>
</div>
</div>
<div class="panel panel-default">
<div data-toggle="collapse" data-target="#panel3" class="panel-heading collapsed">
<h4 class="panel-title">
<a> Panel 3 </a>
</h4>
</div>
<div id="panel3" class="panel-collapse collapse">
<div class="panel-body">
</div>
</div>
</div>
jQUERY
$(".panel .panel-collapse").on('shown.bs.collapse', function ()
{
var active = $(this).attr('id');
$.cookie('activePanelGroup', active);
});
$(".panel .panel-collapse").on('hidden.bs.collapse', function ()
{
$.removeCookie('activePanelGroup');
});
var last = $.cookie('activePanelGroup');
if (last != null)
{
//remove default collapse settings
$(".panel .panel-collapse").removeClass('in');
//show the account_last visible group
$("#" + last).addClass("in");
}
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With