catarina melim
catarina melim

Reputation: 17

How to remember current toggle state in this example after page refresh with local storage?

I have 3 tabs: 'Monday', 'Tuesday' and 'Favorites'. Each tab contains boxes with an empty heart at start ('.favorite i'). I want to save the current toggle class after refresh.

Toggle:

heartLink.find('i').toggleClass('fa-heart-o fa-heart'); // .selected or not

I've started with:

if (heartLink.find('i').hasClass('fa-heart-o')) {
  localStorage.setItem('displayIcon', 0);
 } else {
  localStorage.setItem('displayIcon', 1);
 }

And then I know I will need something similar to this but don't know how to do it..

To make clear: I want to save the current state of each specific heart. I don't one icon to affect all boxes.

var showIconToggle = localStorage.getItem('displayIcon');
if (showIconToggle == 'true') {
    // some code
}

HTML:

   <section id="speakers-programme">
     <div class="container">
       <div class="tabs_main">

          <div class="col-md-5"><a data-target="#mon" class="btn active" data-toggle="tab">Monday</a></div>
          <div class="col-md-5"><a data-target="#tue" class="btn active" data-toggle="tab">Tuesday</a></div>
          <div class="col-md-2"><a data-target="#fav" class="btn active" data-toggle="tab"><i class="fa fa-heart" aria-hidden="true"></i></a></div>

       </div>

       <div class="tab-content">

         <div class="tab-pane active" id="mon">
           <br>
           <div class="spaces">
             <div class="box-container">
               <div class="box not-selected" id="box1">
               <a href="#" class="favorite"><i class="fa fa-heart-o" aria-hidden="true"></i></a>
             </div>
            </div>
            <div class="box-container">
             <div class="box not-selected" id="box2">
               <a href="#" class="favorite"><i class="fa fa-heart-o" aria-hidden="true"></i></a>
             </div>
            </div>
         </div>

        </div>

        <div class="tab-pane active" id="tue">
           <br>
           <div class="spaces">
           </div>
        </div>

        <div class="tab-pane active" id="fav">
           <br>
           <div class="spaces">
           </div>
        </div>


        </div>
     </div>
  </section>

JS:

$('div.tab-pane').on('click', '.favorite', function(e) {
      e.preventDefault();

        var heartLink = $(this);

      //TOGGLE FONT AWESOME ON CLICK
      heartLink.find('i').toggleClass('fa-heart-o fa-heart'); // .selected or not, you need those 2 classes to toggle.

      if (heartLink.find('i').hasClass('fa-heart-o')) {
        localStorage.setItem('displayIcon', 0);
      } else {
        localStorage.setItem('displayIcon', 1);
      }


});

var showIconToggle = localStorage.getItem('displayIcon');
   if (showIconToggle == 'true') {
     // some code here
}

Fiddle: https://fiddle.jshell.net/itsfranhere/1q93a6x1/9/

Upvotes: 0

Views: 1001

Answers (3)

Joshua K
Joshua K

Reputation: 2537

If you want to use just one variable you can use a bitmask.

Theory If you want to save 5 states, the binary value has 5 digits. In decimal it's a variable between 0 and 31.

First the easy part: How can I read out a state? Let's say the actual state is 31 (11111) and we want to know the value of the third digit. How can we do this? Just bitwise and the state with a bitmask where all digits are zero except the digit we want to know:

11111 & 00100 = 00100

If the result is greater than zero, this digit is set.

To create the bitmask just shift a 1 by the amount of digits you want to take a look: 1 << 2 = 00100

Now the "though" part: Setting and unsetting a bit

To set a bit you have to bitwise or the bitmask:

00000 | 00100 = 00100

If this bit is already set... no problem it will be set afterwards.

If you want to unset a bit it's a bit tricky: You can xor the bitmask, but if the bit wasn't set before it's now set.

00100 ^ 00100 = 00000, BUT
00000 ^ 00100 = 00100 (now it's set. It's a trigger, not an unset)

The way you can be sure is: create the inverted bitmask and use bitwise and:

00100 & (00100 ^ (11111)) = 00100 & 11011 = 00000, AND
00000 & (00100 ^ (11111)) = 00000 & 11011 = 00000

Now let's code

For this you take the position of the heart in the dom and use it as an exponent to the base of 2. If you want to set a heart, add this value, if you want to remove it subtract it (Or in bitwise operations: | (or) for adding and & (and) for removing).

saving the actual state:

var $heartLinks = $('.favorite');
var $heartLink = $(this);
var position = $heartLinks.index($heartLink); // this is the position inside the bitmask

var actualBitmask = parseInt(localStorage.displayIcon || '0', 10);
var bit = (1 << position);
var invertedBit = bit ^ ((1 << $heartLinks.length) - 1);
if(!$heartLink.find('i').hasClass('fa-heart-o'))
    actualBitmask |= bit;
else
    actualBitmask &= invertedBit;
localStorage.setItem('displayIcon', actualBitmask);

and calling it when site is ready:

var showIconToggle = localStorage.displayIcon || 0;
$heartLinks.map(function(idx) {
  if((showIconToggle & Math.pow(2,idx)) > 0)
    $(this).find('i').toggleClass('fa-heart-o fa-heart');
});

working fiddle

Upvotes: 1

Sidney
Sidney

Reputation: 4775

As you've seen, you need to store each heart individually.

Here's how I'd do it: in the HTML, give each heart an id. When a heart is clicked, save the new state in localstorage under favorite:id where id is replaced with the heart's id.

When the page loads, grab every heart on the page, and look up its favorite status using its id.

Example: https://fiddle.jshell.net/1q93a6x1/10/

Upvotes: 1

Louys Patrice Bessette
Louys Patrice Bessette

Reputation: 33933

This is a question folowing up that one.

To save your not cloned element states (favorited or not), add this:

At the end of the click handler, save the classes for the clicked i.

// save this current toggle state
localStorage.setItem(box.attr("id"), $(this).find("i").attr("class"));
console.log($(this).find("i").attr("class"));

On page load, before loading the favorites from localStorage, apply those saved classes:

// Load heart's element states
$(".box").each(function(){
  console.log( $(this).attr("id") );
  console.log( localStorage.getItem($(this).attr("id")) );

  if(localStorage.getItem($(this).attr("id")) != null){
    $(this).find("i").removeClass().addClass( localStorage.getItem($(this).attr("id")) );
  }
});

CodePen v5

Upvotes: 1

Related Questions