w3school variable read not guardar expires cookie jquery twitter-bootstrap-3 jquery-cookie

jquery - variable - Guardar el estado contraído de varios paneles utilizando cookies con $.cookie()



jquery cookie (5)

Estoy tratando de determinar cómo puedo guardar el estado colapsado de un panel plegable usando $ .cookie.

This pregunta ha sido útil hasta ahora, pero aún falta la solución final.

Todas las soluciones que he encontrado hasta ahora solo han guardado el último panel desplegado, de modo que cuando la página se vuelve a cargar, el único panel guardado es el último.

Lo que necesito es guardar todos los paneles que se despliegan en lugar de uno solo.

Link al plugin jCookie en Github.

Link a la demo en JSFiddle

ACTUALIZAR

Se ha sugerido que LocalStorage es una solución más apropiada para lo que estoy tratando de lograr. Si puede comentar por qué y qué almacenamiento local es eso sería muy apreciado.

ACTUALIZACIÓN 2

debido a la sugerencia de que el almacenamiento local sería una mejora en el uso de cookies para este problema. La respuesta seleccionada se basó en esto. Sin embargo, como lo mencionó Robin, hay desventajas en el uso de esta técnica en los sitios HTTPS.

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"); }


Debería guardar los paneles activos en una matriz y almacenarlos en una cookie, en lugar de eso, solo se guarda 1 id a la vez.

Tu JS debería ser así:

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


Esto creará una cookie para cada panel cuando se muestre y eliminará la cookie cuando el panel esté oculto.

$(".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); });

Entonces, al cargar el documento, verificamos cada cookie y expandimos el 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"); } } });

UTILIZANDO ALMACENAMIENTO LOCAL

Sin embargo, como alguien sugirió, usar localStorage puede ser una mejor opción. localStorage es ideal para esto.

$(".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 });

Cuando cargue la página, obtenga los valores de localStorage y muestre los paneles.

$(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"); } } });

EDITAR: Verlo en funcionamiento: FIDDLE


Prefiero usar localStorage que cookies.

Solo necesita crear una variable en el almacenamiento local para cada panel asociado a su ID, donde almacena el estado del panel.

Al cargar la página, simplemente haga un bucle con todos los objetos clasificados en el panel, verificando su variable asociada en el almacenamiento local y aplicando clases apropiadas según el valor.


Puede tener la configuración en una sola cookie (es decir, separadas por comas) y actualizarla en abrir-cerrar.

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

Vea su ejemplo de JsFiddle editado trabajando here .

EDITAR

Estoy de acuerdo con Chris. Creo que es una solución más elegante tener todos los valores almacenados en una sola cookie, sin embargo, debemos tener en cuenta las limitaciones del tamaño de una sola cookie . (Esto varía según el navegador).


<!-- 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>

Permítame agregar una alternativa adicional: si ha personalizado el ejemplo del panel de inicio como yo y terminó con el anidamiento múltiple para su acordeón, asumiendo que tiene identificadores únicos para su elemento de colapso y expansión (el panel que se expande o colapsa), puede atrapar el evento de clic (depender de) para obtener el ID del panel colapsando / expandiendo, sin importar qué tan profundo esté ubicado en el anidamiento.

Personalicé los ejemplos en para lograr esto; básicamente obtiene el ID del panel expandido en el evento de clic, crea una cookie con el ID como nombre (var temp) que se usará para eliminarlo más adelante si el panel está contraído. Luego haga un bucle a través de la cookie en la actualización de la página (o etc.) para restaurar el estado del acordeón. Debo mencionar que las cookies no son recomendables para este tipo de especificaciones. Por lo tanto, puede cambiar el código para usar la matriz localStorage o Javascript. Espero que esto ayude a alguien.

$(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"); } } }