Why isn't my cookie updating? - javascript

I am making a dark mode for a site using a button toggle. To keep the dark mode saved when changing pages, I am using cookies. When pressing the toggle again, the dark mode is disabled but is not saving and I am not sure why.
Ps. I am new at javascript so this may be a dumb mistake.
if ($.cookie('darkModeOn')){
$('html').toggleClass('dark-mode');
$('#dark-toggle').click(function(){
$.cookie('darkModeOn', false, { expires: 7 });
$('html').toggleClass('dark-mode');
});
}
else
{
$('#dark-toggle').click(function(){
$.cookie('darkModeOn', true, { expires: 7 });
$('html').toggleClass('dark-mode');
});
}

When you press the toggle button you also want to toggle the True/False value of the cookie. Now you always either set it to True or to False depending on the first state.
Use ! $.cookie('darkModeOn') as value to store into the cookie to automatically toggle the boolean value.
EDIT
It was indeed not working, and I found out that it was not working because of the boolean values.
The boolean values are stored as string ("false" and "true") since if ( "false") gives boolean true, the if is always executed. When you use integers instead of booleans this would work, but you can also change the if to:
if ($.cookie('darkModeOn')=="true") //...
If you use integers it also works:
https://jsfiddle.net/6m2ydrh2/12/
$('#dark-toggle').click(function(){
//this gets executed each click so we need to toggle the boolean value.
if ($.cookie('darkModeOn')==0){
$.cookie('darkModeOn', 1, { expires: 7 });
}else{
$.cookie('darkModeOn', 0, { expires: 7 });
}
console.log( "cookie:"+$.cookie('darkModeOn')) ;
$('#test').toggleClass('dark-mode');
});
if ($.cookie('darkModeOn')){
//this is only executed on load
$('#test').toggleClass('dark-mode');
}
See also this post: jquery cookie set value to boolean true.
The boolean values are stored as string and therefor causing problems.

Related

Toggling localStorage item

I want to create a toggle function for my localStorage as I am trying to install a dark mode on my site and I want it to remember the user's choice.
I want it load the current preference on page load, if one has been made, and then toggle the state on click. My code is below - however I am clearly making some error on my attempt to toggle the localStorage state.
// ON PAGE LOAD, IF USER PREFERS DARK, ADD DARK CLASS TO HTML
if (window.localStorage.getItem('preferDark')) {
$('html').toggleClass('dark');
}
// TOGGLE STATE ON CLICK
$('.wrapper').click(function(){
if (window.localStorage.getItem('preferDark', true)) {
window.localStorage.setItem('preferDark', false);
} else {
window.localStorage.setItem('preferDark', true);
}
$('html').toggleClass('dark');
});
I know there are various localStorage toggle questions out there but I can't find one quite the same as mine.
You can't keep boolean in localStorage. That's why you have an error.
Try to keep, for example, 0 for false and 1 for true. But remember that localStorage also can't keep integer - you can pass integer or boolean but it will be converted to string.
Try this:
if (+window.localStorage.getItem("preferDark")) {
$("html").toggleClass("dark");
}
$(".wrapper").click(function () {
if (+window.localStorage.getItem("preferDark")) {
window.localStorage.setItem("preferDark", 0);
} else {
window.localStorage.setItem("preferDark", 1);
}
$("html").toggleClass("dark");
});
Pay attention: I use + sign before getting value from localStorage to convert it to Number

Is there a way to hijack what is in the DOM?

When I console.log a value, I get immediate response. But, the html takes time.
I know what the issue is and it has nothing to do with async or anything.
Is there a way to get what you are console.logging without doing a return?
Possibly saving it in localStorage.
"status" comes from third party API where it's boolean.The value changes from true to false based on user input. Which is correct. But, HTML takes time for it to change in timely manner
public elementEvent($event) {
this.isValid = $event.status;
console.log($event.status);
}
//output: true
<div>{{isValid}}</div>
//output: false
So here is what I had to do:
public elementEvent($event) {
this.isValid = $event.status;
this.ref.detectChanges();
}

Vanilla JavaScript if clause executes when false

This is my first post and I am thankful in advance for all the support.
Short background:
I am part of a script team developing a script to make our tasks easier. We are using a MySQL DB to allow the team choose which features we create each wants to use. The DB is working fine, as well as the data retrieval.
Issue:
Even though the cookies we create are set to hold the boolean value False, a function is always executing the if clause it holds.
function tkAlwaysViewAll(snippet) {
console.log('Viewall: ' + snippet);
if (snippet) {
var ticketURL = window.location.href;
var showAllURL, x;
x = ticketURL.indexOf('block=');
// if the string 'block=' does not exist in the URL, it adds the parameter and
// reloads the ticket to the correct 'view all' URL
if (x == -1) {
showAllURL = ticketURL + '&block=15:.a';
window.location.href = showAllURL;
} else {
console.log('Viewall function executed');
}
}
}
The code above should execute only when the value of snippet is set to True. However, it is being executed always, ignoring the value of snippet. Below you see the output of the console.log() which has been included for the debugging only.
The first console.log() displays the value of the snippet variable.
The second console.log() will be displayed only after the page has been reloaded (or when directly using the link with the 'block' parameter, but we are aware of this and not using it).
When snippet is True:
Viewall: true
Viewall function executed
And when the snippet is False (function should not be executed):
Viewall: false
Viewall function executed
The function is not using any global variables nor being altered by any other events.
What am I doing wrong in this function?
Best regards
The reason is that you pass a String "false" to your function (cookies always store Strings). Putting that in an if() condition internally converts that String to a Boolean value. Non-empty strings are converted to true in that mechanism.
Here's what Javascript does with non-Boolean values when converting:
// converts val to Boolean and returns it
function truthy(val) {
return Boolean(val)
}
console.log(truthy("true")) // true
console.log(truthy("false")) // true
console.log(truthy("")) // false
console.log(truthy(1)) // true
console.log(truthy(0)) // false
console.log(truthy([])) // true
console.log(truthy([].length)) // false
console.log(truthy({})) // true

Cannot switch between classes with jQuery

I've got a problem with switching between element classes - probably sth stupid, but I couldn't find the answer.
In my system I display a list of items. Now I want to be able to promote items, so that they appear at the top of the list. I created some backend infrastructure which works ok and added things to my frontend: a star (a span with star bg) next to every item's title and a jQuery script which is supposed to:
listen to 'click' event - when I click on a star
get some data- attributes from the span
post them to my controller
the controller checks if I'm allowed to promote items and replies 'true' or 'false'
if 'true' then I switch between 'gold-star' and 'silver-star' classes of the item
For some reason the classes don't switch - only when I refresh the page I can see the effect. I tried debugging with Firebug - it gets to the toggle line, but then nothing happens.
Here's the code:
<span class="silver-star promote">
$(".promote").bind("click", function() {
var $this = $(this);
var itemId = $this.attr("data-id"),
isPromoted = true;
if ($this.hasClass("gold-star")) {
isPromoted = false;
}
$.post('/promoteitems', { itemId: itemId, isPromoted: isPromoted }, function(allowPromotion) {
if (allowPromotion == true) {
$this.toggleClass("silver-star").toggleClass("gold-star");
}
});
});
Thanks in advance!
When you are getting a response back it might not recognise it as a boolean simple test would be to check response as string
From your comment on the question:
...the allowPromotion value is 'True' (with a capital T)...
That tell us it's a string, not a boolean. You don't want to just do if (allowPromotion), because that will toggle the classes even if you get back "False".
Instead:
if (allowPromotion == "True") { // Note the quotes and capital T
// ...toggle the classes
}
Or if you want to allow for possibly getting back something with a lower-case T at some point in the future:
if (/^\s*true\s*$/i.test(allowPromotion)) {
// ...toggle the classes
}
That's over-engineering it a bit (it'll work with "True", "true", " True " [note the spaces], and even an actual boolean true)...

Boolean value not being passed with jQuery/ $.get - Why?

I have my front end script which has the following jQuery code:
$.get("/backend/post.php", {
title: title,
message: post,
stick: sticky
}, function (output) {
alert("Call Back");
}
}, "json");
stick is a boolean value, the other two are strings. I've confirmed that they are in fact set. Now on the backend page, using $_GET, title and, message and being passed, but $_GET['stick'] is returning empty, and the PHP function gettype() is telling me it is NULL.
In request to one of the comments:
sticky comes from a form, it's a check box and I just select it with this code:
var sticky = $("input[name=sticky]").attr('checked');
When I use alert() to output the value of sticky, it will return true/false depending on what was selected.
Why is this boolean value not being passed? The JSON site tells me you can have the boolean values true/false in it. But it is not working here for some reason.
I can't be entirely sure because I haven't tested it myself, but I think this is related to how GET requests transfer as strings. Try something like this:
var sticky = $("input[name=sticky]").attr('checked')?"true":"false";
$.get("/backend/post.php", {
title: title,
message: post,
stick: sticky
}, function (output) {
alert("Call Back");
}
}, "json");
It's entirely likely that this won't work, but give it a try.
If in a form an input does not have a value it will not be sent as a parameter. So the absence of of a $_GET['stick'] is equivalent to the query string parameter stick=false. So if you must have a parameter:
var sticky = 'true';
if($("input[name=sticky]").not(':checked')) {
sticky = 'false';
}

Categories