Вопрос

I have a series of divs that are toggled with Bootstrap's toggle jQuery. I need to create a cookie that remembers and preserves the toggled state of the divs. I'm attempting to set the toggled states to a json string (as recommended by here) in order to only have one cookie.

I've run into a snag that I can't seem to get passed. The json array is getting created, but it's always one behind, so to speak.

The jQuery:

$('#style-widget [data-toggle="collapse"]').on('click', function() {

var check_open_divs = [];
var toggled_div = $('#style-widget [data-toggle="collapse"]:not(.collapsed)');

// PROBLEM BELOW ▼ -- on initial click the data attribute is not going into the array
// on second click (when the class 'toggled' is being added by Bootstrap code) the 
// data attribute is added to the array

$(toggled_div).each(function() {
  check_open_divs.push($(this).attr('data-target'));
});

// stringify array object
check_open_divs = JSON.stringify(check_open_divs);

$.cookie('bg-noise-div-state', check_open_divs, {expires:365, path: '/'});

});

The (simplified) HTML:

<div id="style-widget">

  <!-- div one -->
  <p title="click to toggle" class="collapsed" data-toggle="collapse" data-target="#background-noise-wrap">Background Noise</p>
  <div id="background-noise-wrap" class="collapse">
    <!-- content here, removed for brevity -->
  </div>

  <!-- div two -->
  <p title="click to toggle" class="collapsed" data-toggle="collapse" data-target="#extra-header-selection-wrap">Extra Header</p>
  <div id="extra-header-selection-wrap" class="collapse">
    <div class="selection-wrap first">
     <!-- content here, removed for brevity -->
    </div>
  </div>

  <!-- div three -->
  <p title="click to toggle" class="collapsed" data-toggle="collapse" data-target="#wide-or-boxed-wrap">Wide or Boxed?</p>
  <div id="wide-or-boxed-wrap" class="collapse">
    <p>Header &amp; Footer</p>
    <div id="wide-boxed-selection-wrap">
      <!-- content here, removed for brevity -->
    </div>
  </div> 

</div>

By default the divs are collapsed, which is why they initially have the .collapsed class. In pseudo-code thinking:

1. create function on click of collapse toggle (the p tag)
2. select divs that are not collapsed
3. save these to a json string, then cookie
4. check for this cookie on page load to persist the toggled states

Much obliged for any insights.

Это было полезно?

Решение

You need to encapsulate the cookie creation into a function and then call the function after toggling the class.

$('[data-toggle="collapse"]').on('click', function() {

    // toggle your div class here
    $(this).toggleClass('expanded collapsed');

    // call function to store value
    storeState();

 });

function storeState() {
    var check_open_divs = [];
    var toggled_div = $('#style-widget [data-toggle="collapse"]:not(.collapsed)');

    $(toggled_div).each(function() {
      check_open_divs.push($(this).attr('data-target'));
    });

    // stringify array object
    check_open_divs = JSON.stringify(check_open_divs);
    console.log(check_open_divs);

    $.cookie('bg-noise-div-state', check_open_divs, {expires:365, path: '/'});
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top