Local Storage Not Working When Applying Dark Mode - javascript

I am trying to apply Dark Mode To My Website. I am using the code given below to do so.
!(function () {
var t,
e = document.getElementById("darkSwitch");
if (e) {
(t =
null !== localStorage.getItem("darkSwitch") &&
"dark" === localStorage.getItem("darkSwitch")),
(e.checked = t)
? document.body.setAttribute("data-theme", "dark")
: document.body.removeAttribute("data-theme"),
e.addEventListener("change", function (t) {
e.checked
? (document.body.setAttribute("data-theme", "dark"),
localStorage.setItem("darkSwitch", "dark"))
: (document.body.setAttribute("data-theme", "light"),
localStorage.setItem("darkSwitch", "dark"));
});
}
})();
You can check it out here http://anayaadventure.com/
Everything is working fine but the problem is now suppose I turn the dark mode off and I refresh the page, then the page again loads in dark mode. Why is this happening and how can I solve it.
Thanks for any kind of help in advence.

It looks like you never set localstorage back to "light" in the toggle-event
e.checked
? (document.body.setAttribute("data-theme", "dark"),
localStorage.setItem("darkSwitch", "dark")) //set to dark
: (document.body.setAttribute("data-theme", "light"),
localStorage.setItem("darkSwitch", "dark")); //set item to "light" instead of "dark" ?
And if you edit the local storage value manually to "light" it goes back to lightmode
so i think you want to change the last line to localStorage.setItem("darkSwitch", "light"));
Addition to that i like the layout and design of the site!

Related

Why the Toggle buttons are flashing on reload?

When i reload my page, my toggle-buttons which are hidded by making opacity-0 appears on flash.
Is there any way to stop these flashes from appearing on reload and keep the (opacity-0) items hidden as intended?
Live Site URL
Codebase-Github Repo
//loads user preference after reload based on user's previous session
window.onload = () => {
"toggle1" == localStorage.getItem("clicked")
? (toggleHide("toggle1"), theme1())
: "toggle2" == localStorage.getItem("clicked")
? (toggleHide("toggle2"), theme2())
: "toggle3" == localStorage.getItem("clicked")
? (toggleHide("toggle3"), theme3())
: console.log("infinity");
};
One solution is to make all three themes hidden by default and onload method, you decide which theme you want to show, and by default, if there no clicked item in the localStorage show the first theme, and this will prevent flashing.
window.onload = () => {
"toggle1" == localStorage.getItem("clicked")
? (toggleHide("toggle1"), theme1())
: "toggle2" == localStorage.getItem("clicked")
? (toggleHide("toggle2"), theme2())
: "toggle3" == localStorage.getItem("clicked")
? (toggleHide("toggle3"), theme3())
: (toggleHide("toggle1"), theme1())
};

how can i change the state value with setState with one click

how can i update the activeUrl value with setState ?
the state is
state = {
activeUrl: ''
}
the function
const handleActiveMenu = () => {
let splitUrl = window.location.href.split('/')
let assignActive = splitUrl[4]
this.setState({ activeUrl: assignActive })
}
the component
<Link
className={`${activeUrl === '' ? classes.borderBottom : null}`}
onClick={() => handleActiveMenu}
to="/"
>
Beranda
</Link>
<Link
className={`${
activeUrl === 'profil' ? classes.borderBottom : null
}`}
onClick={handleActiveMenu}
to="/profil"
>
Inisiatif
</Link>
when i trying to console.log, the activeUrl doesnt change , but after i click for 2 times, the value was change..
As far as I see, a onclick on a Link (if that is the Link from react-router-dom) may not be working. Try out a log.console or debugging if the handleActiveMenu is reached.
Additional to that, when I interpret your code correctly, you want to set the active URL after clicking the link -> You should not do that within a onClick in the Link component, try to do that within the component you called e.g. in the componentDidMount event.

Toggle icon color upon button click using React Hooks

I'm a newbie to React. I'm trying to update the like or bookmark count to 0 and 1 upon button click. When I click on the bookmark icon, both the icons gets toggled. The behavior seems inconsistent.
ToggleIcon Component
const ToggleIcon = ({ icon, color, styledIcon, handleClick }: any) => {
return (
<IonIcon icon={color ? styledIcon : icon} onClick={handleClick}></IonIcon>
);
};
Root Component
{config.map((props, index) => (
<ToggleIcon
style={{ padding: "10px" }}
handleClick={() => {
setColor(!color);
if (props.type === "bookmark") {
!color && props.type === "bookmark"
? setBookmarkCount(bookmarkCount + 1)
: setBookmarkCount(bookmarkCount - 1);
}
if (props.type === "like") {
!color && props.type === "like"
? setLikeCount(likeCount + 1)
: setLikeCount(likeCount - 1);
}
}}
color={color}
{...props}
/>
))}
I created a working example using CodeSandbox. Could anyone please help?
The root cause of your problem is using a single color state to toggle the icon color. Whenever you click on any icon it triggers a change in the color state which rerenders the entire component with that color state.
I tried using multiple states for LikeColor and BookColor and it worked like a charm.Solution Link
Solution: Codesandbox
You need to separate the color into two different states. The way you have it written, one boolean value is driving the color for both the bookmark and icon color on line 27. Just because you have a loop on line 51 does not change the fact that there is only one setColor function, which you end up using twice for both <ToggleIcon/>
I suppose by now you are better in react. Just pointing out for someone else who might need this solution. Your conditional statement inside handleClick is a bit messed up
if (props.type === "bookmark") {
!color && props.type === "bookmark"
? setBookmarkCount(bookmarkCount + 1)
: setBookmarkCount(bookmarkCount - 1);
}
if (props.type === "like") {
!color && props.type === "like"
? setLikeCount(likeCount + 1)
: setLikeCount(likeCount - 1);
}
}}
color={color}
{...props}
Should include an else statement instead of 2 if(s) statements see docs below
https://reactjs.org/docs/conditional-rendering.html

How do I prevent dark mode from resetting when loading page?

I read that either local storage or session storage would do the trick, but I'm having a hard time trying to make it work.
function changeStyleByClass(className, classToggle){
var element = document.getElementsByClassName(className);
for (var i=0; i < element.length; i++) {
element[i].classList.toggle(classToggle);
}}
document.getElementById("bulb").addEventListener("click", () => {
changeStyleByClass("bgcolor-lightdark", "dark-mode");
changeStyleByClass("nav", "dark-mode");
changeStyleByClass("nav-item", "dark-mode");
changeStyleByClass("card", "dark-mode");
changeStyleByClass("container", "dark-mode");
changeStyleByClass("bulbicon","dark-mode");});
I'd like to navigate through pages and still keep the theme that is currently on.
Thanks in advance!
You can use localStorage.setItem to store data and localStorage.getItem to retrieve data. One thing that I've noticed is that your light bulb button turns dark mode on, but doesn't turn dark mode off. I have a solution that also simplifies your process of changing themes.
var togButton = document.getElementById("togButton");
//Check localStorage
//It's commented out because it doesn't work in Stack Overflow snippet
//darkOn = localStorage.getItem("dark") == "true" ? true : false;
setTheme();
function setTheme(){
//Save to localStorage
//It's commented out because it doesn't work in Stack Overflow snippet
//localStorage.setItem("dark", darkOn ? "true" : "false");
if(darkOn){
document.body.setAttribute("theme", "dark");
togButton.innerHTML = "Turn off dark mode.";
}
else{
document.body.setAttribute("theme", "light");
togButton.innerHTML = "Turn on dark mode.";
}
}
var darkOn = false;
function toggle(){
darkOn = !darkOn;
setTheme();
}
togButton.addEventListener("click", toggle);
/*By doing body[theme=dark] it only takes effect if the <body> tag has an attribute called theme which is dark.*/
body[theme=light] .sampleClass{
color: black;
background-color: white;
}
body[theme=dark] .sampleClass{
color: mediumseagreen;
background-color: black;
}
<body>
<h1 class="sampleClass">Theme changes.</h1>
<button id="togButton">Turn on dark mode.</button>
</body>
This method is easier because you don't need to manually type all of the classes you want to turn to dark mode, you can just have bot dark and light modes in the CSS file.
I hope you understand the javascript + css. Good luck and ask me if you can't understand part of it.
Edit: Called setTheme() right away.
Edit 2: Explanation
The part which is localStorage.getItem("dark") == "true" ? true : false" is called turnary. The turnary syntax is condition ? value if true : value if false. It is basically the same thing as doing
if(localStorage.getItem("dark") == "true"){
darkOn = true;
}
else{
darkOn = false;
}
This is because localStorage is like a Map where the keys and values are both strings.
Moving on to the next part.
darkOn = false; Just declares the variable darkOn and by default it if false. The toggle function changes darkOn to be the opposite of what it is. the exclamation mark negates boolean values, so darkOn = !darkOn; turns darkOn to false if it was previously true, and true if it was previously false.
Then it calls the setTheme function to update the theme attribute in the <body> tag, causing the css to change. It also saves the current value to localStorage.

How to disable NEXT button on step 1 of FuelUX Wizard

I am creating a wizard control pages using the FuelUX wizard plugin
http://getfuelux.com/javascript.html#wizard
And I am trying to disable the NEXT button only on the STEP1 of the wizard.
Kindly check this image for better understanding:
http://i.imgur.com/xlhwu2j.png
I would love to have some help on this. Let me know if need anything from my side.
Ok. After much research I just have this solution for you. You need to modify the plugin fuelux.js. Take unminified version of fuelux.js and find below line of code
var canMovePrev = ( this.currentStep > 1 ); //remember, steps index is 1 based...
var isFirstStep = ( this.currentStep === 1 );
var isLastStep = ( this.currentStep === this.numSteps );
// disable buttons based on current step
if ( !this.options.disablePreviousStep ) {
this.$prevBtn.attr( 'disabled', ( isFirstStep === true || canMovePrev === false ) );
}
// change button text of last step, if specified
var last = this.$nextBtn.attr( 'data-last' );
if(isFirstStep) //Add this line
{
this.$nextBtn.attr( 'disabled', ( isFirstStep === true || canMoveNext === false ) );
}
The above line you can find it in setState: function() { which is in
Line number 3652
Let me know if you face any issue
EDIT: and to work with you alternate next button you can write it as below
$(document).ready(function(){
$('.btnext').on('click',function(){
$('.wizard').wizard('next');
$nextBtn = $('.wizard').find( 'button.btn-next' );
$nextBtn.removeAttr('disabled');
});
});
Add your alternate button wherever you want and just add a class btnext to it.
I really tried all the suggestions given by peoples. I dont know why none seemed to work for me. May be bacause I didn't provide enough information. Out of several methods I tried. I found this one to be the easiest.
protected void NextButton_Click(object sender, WizardNavigationEventArgs e)
{
//Suppose You have a control on your webpage. Just check if it has
//the information you require. In my case lblpasskeytextbox
//and if the condtion is not fulfilled I am not letting user to move
//next page
if (lblPasskeyInformation.Text[0] == 'I')
{
e.Cancel = true;
return;
}
}
After reading the fuel ux documentation, here seems to be a hack that allows you to disable a specific step without modifying any source fuelux.js code.
$wizard.on('actionclicked.fu.wizard', function (evt) {
//Check the current step
var currentStep = $wizard.wizard('selectedItem').step;
//If current step needs to be disabled, disable it and then return.
if (currentStep === 1)
{
evt.preventDefault();
return;
}
});
Please note that $wizard here is just my way of saying $('#myWizard') as described in the fuel ux documentation.

Categories