Reputation: 17
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
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
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
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")) );
}
});
Upvotes: 1