JS dark theme not changing - javascript

I'm trying to make light/light theme for a table in my project,its dark by default so i'm trying to change it to light when i click on the button but when i click it changes to light but not turning back any hints ?
var element = document.getElementById('toggleTheme')
var attributeContent = element.getAttribute('data-layout-mode')
let toggleTheme = document.querySelector(".light-dark-mode");
let styleSheet = document.querySelector("#color-theme");
console.log(attributeContent);
if (attributeContent=="dark") {
toggleTheme.addEventListener("click", () => {
styleSheet.setAttribute("href", "")
})
} else if (attributeContent=="light") {
toggleTheme.addEventListener("click", () => {
styleSheet.setAttribute("href", "{{ asset('css/style.css') }}")
})
} else {
console.log("not found")
}

You only define what to toggle based on the initial value of the attributeContent.
You should better do the test, on whether it is currently dark or light, each time the toggle is clicked.
something like
var element = document.getElementById('toggleTheme')
let toggleTheme = document.querySelector(".light-dark-mode");
let styleSheet = document.querySelector("#color-theme");
toggleTheme.addEventListener("click", function() {
// read the layout mode
var attributeContent = element.getAttribute('data-layout-mode');
if (attributeContent == "dark") {
styleSheet.setAttribute("href", "");
// set the layout mode to the new value
element.setAttribute('data-layout-mode', 'light');
} else if (attributeConten == "light") {
styleSheet.setAttribute("href", "{{ asset('css/style.css') }}");
// set the layout mode to the new value
element.setAttribute('data-layout-mode', 'dark');
} else {
console.log("not found")
}
})

Related

Use Javascript document.body.className to add a body class rather than document.body.setAttribute

I'm using the function below to toggle dark mode in CSS. It uses document.body.setAttribute to add the attribute data-theme="dark" to the document body tag, and removes it when toggled again; and the function reads and/or sets localStorage darkSwitch to hold the dark mode state between page loads. The CSS is i.e. [data-theme="dark"] .myselector {background-color: #000;}.
Function:
<input type="checkbox" class="custom-control-input" id="darkSwitch" /> // Simply the button to toggle
(function() {
var darkSwitch = document.getElementById("darkSwitch");
if (darkSwitch) {
initTheme();
darkSwitch.addEventListener("change", function(event) {
resetTheme();
});
function initTheme() {
var darkThemeSelected =
localStorage.getItem("darkSwitch") !== null &&
localStorage.getItem("darkSwitch") === "dark";
darkSwitch.checked = darkThemeSelected;
darkThemeSelected
? document.body.setAttribute("data-theme", "dark")
: document.body.removeAttribute("data-theme");
}
function resetTheme() {
if (darkSwitch.checked) {
document.body.setAttribute("data-theme", "dark");
localStorage.setItem("darkSwitch", "dark");
} else {
document.body.removeAttribute("data-theme");
localStorage.removeItem("darkSwitch");
}
}
}
})();
What I want to do is modify the function to not add the data attribute data-theme but instead add the body class dark so the CSS will be i.e. body.dark .myselector {background-color: #000;}.
This is my attempt below to add the body class dark to the body tag, but of course, it doesn't work. I'm trying to use document.body.className and document.body.className.replace. How can I get this to work?
(function() {
var darkSwitch = document.getElementById("darkSwitch");
if (darkSwitch) {
initTheme();
darkSwitch.addEventListener("change", function(event) {
resetTheme();
});
function initTheme() {
var darkThemeSelected =
localStorage.getItem("darkSwitch") !== null &&
localStorage.getItem("darkSwitch") === "dark";
darkSwitch.checked = darkThemeSelected;
darkThemeSelected
? document.body.className("dark")
: document.body.className.replace("dark","");
}
function resetTheme() {
if (darkSwitch.checked) {
document.body.className("dark");
localStorage.setItem("darkSwitch", "dark");
} else {
document.body.className.replace("dark","");
localStorage.removeItem("darkSwitch");
}
}
}
})();

Preserve Navigation bar (Hide/Show) when navigated to Other module

How to preserve the navigation bar (minimized position) when navigated to other module.
Collapsed Navigation Bar
sidebar-collapse will not preserve if navigated to other page.
Do you want your nav-bar to change from big to small when you move to a different place?
(sorry, I'm not allowed to comment yet).
Do you want your nav-bar to change from big to small when you move to a different place? It is always nice if you add some code :)
const menuToggle = document.querySelector('.menu-toggle');
const mainUl = document.querySelector(".main-ul");
const navBtn = document.querySelectorAll(".nav-a");
// Open and close meny on click
menuToggle.addEventListener("click", function () {
menuToggle.classList.toggle("open");
mainUl.classList.toggle("open");
});
// Close menu when clicked on an a-tag in the menu
navBtn.forEach((button) => {
button.addEventListener("click", function () {
navBtn.forEach((button) => button.classList.remove("active"));
this.classList.add("active");
mainUl.classList.toggle("open");
menuToggle.classList.toggle("open");
});
});
This is demo and source code I created
https://minhhungit.github.io/2020/10/16/011-keep-menu-toggle-state-after-page-reload/
namespace J {
export function storageSet(name, val) {
if (typeof (Storage) !== "undefined") {
localStorage.setItem(name, val);
} else {
//window.alert('Please use a modern browser to properly view this template!');
}
}
export function storageGet(name) {
if (typeof (Storage) !== "undefined") {
return localStorage.getItem(name);
} else {
return null;
}
}
}
In _Layout.cshtml put this code
<script type="text/javascript">
$().ready(function () {
new DailyTimelog.Common.SidebarSearch($('#SidebarSearch'), $('#SidebarMenu')).init();
// ...
// ...
$(window).bind("load resize layout", doLayout);
doLayout();
});
</script>
// Add these lines
<script type="text/javascript">
let sidebarToggleButton = $('.main-header .sidebar-toggle');
if (sidebarToggleButton) {
$(sidebarToggleButton).on('click', function (e) {
e.preventDefault();
let isSidebarCollapse = $('body').hasClass('sidebar-collapse');
J.storageSet('IS_SIDEBAR_COLLAPSE', !isSidebarCollapse);
});
}
</script>
And LeftNavigation.cshtml
<script type="text/javascript">
function openWindow(url, width, height) {
height = height || (screen.availHeight - 60);
// ...
// ...
}
// Add these lines
let isSidebarCollapseCache = J.storageGet('IS_SIDEBAR_COLLAPSE');
if (isSidebarCollapseCache == 'true') {
$('body').toggleClass('sidebar-collapse', true);
}
else {
$('body').toggleClass('sidebar-collapse', false);
}
</script>
``
#minhhungit Thank you for your demo.
I have used cookie implementation similar to ThemePreference.
Views/Shared/_Layout.cshtml
var theme = !themeCookie.IsEmptyOrNull() ? themeCookie : "blue";
// Add following lines
var sbNavCookie = Context.Request.Cookies["SBNavigationPreference"];
var sbNav = !sbNavCookie.IsEmptyOrNull() && sbNavCookie == "true" ? true : false;
in Body Tag,
<body ... class="...#(sbNav?" sidebar-collapse":"")">
In Script Tag,
<script type="text/javascript">
$().ready(function () {
// Add new lines
let sidebarToggleButton = $('.main-header .sidebar-toggle');
if (sidebarToggleButton) {
$(sidebarToggleButton).on('click', function (e) {
e.preventDefault();
let isSidebarCollapse = $('body').hasClass('sidebar-collapse');
$.cookie('SBNavigationPreference', !isSidebarCollapse, {
path: Q.Config.applicationPath,
expires: 365
});
});
}

window.matchMedia Javascript to remember user selection on page change

I'm having trouble with prefers-color-scheme with the logic that I'm trying to achieve. For example, with the prefers-color-scheme I have a toggle on my site that overrides this is a user prefers black while using light mode, and vice versa. The issue I'm running into is I can't toggle it so that when a user changes the toggle to set it to the OS color theme, when they switch pages the theme switches back to the prefers color scheme. I already have local storage setup and variables called theme type and on.
When I comment out the detect color scheme function, the local storage remembers the users desired theme setting. When uncommented it overrides and always picks the theme os color scheme. How can I get my logic working right where when on the users first entry point before the local storage is created that it reads the theme OS but if the user changes the theme to black and vice versa that the OS doesn't override when on page change?
Thanks.
So the detectColorScheme checks users OS theme.
function detectColorScheme(){
var on = 1;
on = 1;
if (window.matchMedia('(prefers-color-scheme: dark)').matches && on <= 1) {
if (on = 1 ) {
on = 2;
darkmode();
console.log("OS Setting DARK MODE");
}
}
if (window.matchMedia("(prefers-color-scheme: light)").matches ) {
if (on = 1) {
lightmode();
console.log("OS Setting LIGHT MODE");
}
}
}
Then at the start of the javascript file I do the following :
document.body.style.backgroundColor = "";
if (localStorage.themepref == 1 ) {
detectColorScheme();
document.body.style.backgroundColor = "#FFF";
lightmode();
}
else {
detectColorScheme();
document.body.style.backgroundColor = "#0a0a0a";
darkmode();
localStorage.themepref = 2;
}
window.onload = function() {
console.log('First');
if (event.target.readyState === 'loading') {
detectColorScheme();
$('body').css({ background: ''});
document.body.style.backgroundColor = "inherit";
if(lightmodeON == true) {
detectColorScheme();
$('body').css({background: "#fbfcfd"});
document.body.style.backgroundColor = "#FFF";
}
if(lightmodeON == false) {
detectColorScheme();
$('body').css({background: "#0a0a0a"});
document.body.style.backgroundColor = "#0a0a0a";
}
}
};
And lastly
document.addEventListener("DOMContentLoaded", function() {
window.scrollTo(0, 0);
$(window).scrollTop( $("#top").offset().top );
$(document).scrollTop(0);
document.body.style.backgroundColor = "";
if (document.readyState === 'complete') {
if(lightmodeON == true) {
$('body').css({background: "#fbfcfd"});
console.log('loading white bg');
}
if(lightmodeON == false) {
$('body').css({background: "#0a0a0a"});
console.log('loading black bg');
}
}
if (typeof (Storage) !=="undefined") {
if (localStorage.themepref == 1 ) {
lightmode();
}
else {
darkmode();
localStorage.themepref = 2;
}
if(lightmodeON == true) {
$('body').css({background: "#fbfcfd"});
console.log('loading fffwhite bg');
}
if(lightmodeON == false) {
$('body').css({background: "#0a0a0a"});
console.log('loading black bg');
}
}
I have done this small effort, What I am doing is:
When user will load the website for first time, localStorage will be empty so we will setup the theme according to OS but then if user plays with our toggle, which if on then lightmode otherwise darkmode, then we will also save this in localstorage and next time when ever user will visit our page, we will check it's preference from the local storage, will never go back to OS theme.
Please have a look and let me know if it is any helpful. It will not work here as localStorage will not be supported here. Please copy and test in your browser.
<html lang="en">
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<label style="color:yellow;">IsLightMode: </label>
<input id="toggleCheck" type="checkBox" onclick="toggle()" />
<script>
var lightmodeOn = true;
function changeColorOfBackground(lightmodeOn) {
if(lightmodeOn == true) {
// you can call your lightmode function here if want to set other things too.
$('body').css({background: "#fbfcfd"});
console.log('loading white bg');
}
if(lightmodeOn == false) {
// you can call your darkmode function here if want to set other things too.
$('body').css({background: "#0a0a0a"});
console.log('loading black bg');
}
}
function toggle() {
lightmodeOn = !lightmodeOn;
changeColorOfBackground(lightmodeOn);
localStorage.themepref = lightmodeOn?1:2;
}
document.addEventListener("DOMContentLoaded", function() {
//if it is not set in localStorage only then check OS theme otherwise always load from localStorage
if(localStorage.themepref === null) {
//if windows is light, then we should go with dark theme
if (window.matchMedia('(prefers-color-scheme: light)').matches) {
lightmodeOn = false;
}
}
else if (localStorage.themepref == 2 ) {
lightmodeOn = false;
}
if(lightmodeOn) {
$('#toggleCheck').prop('checked',true);
}
changeColorOfBackground(lightmodeOn);
});
</script>
</body>
</html>

Is there an any method to implement Night and Day mode on Static html site?

I need to implement Night/Day mode Functionality just like justanotherpanel website i don't have any database but i have admin panel where i write html css and javascript only
is there a way when user login and click on button website mode change into night mode by adding class and when they signout and login again night mode still on...?
ref site used this code
var mode = false ;
$('#nightmode').on('click', function() {
mode = !mode;
if (mode) {
$(this).removeClass('fa-moon-o');
$(this).addClass('fa-sun-o');
daymode = $('.daymode').removeClass('daymode');
daymode.addClass('nightmode');
$.get('/changevariable/custom_variable_1?value=2', function() {
});
} else {
$(this).removeClass('fa-sun-o');
$(this).addClass('fa-moon-o');
nightmode = $('.nightmode').removeClass('nightmode');
nightmode.addClass('daymode');
$.get('/changevariable/custom_variable_1?value=1', function() {
});
}
});
You can use localStorage to set the mode for a website. It'll be stored in the user's browser even after a reload.
$(document).ready(function(){
// Set the website mode when the page is loaded.
var mode = localStorage.getItem('theme');
// Set the selected theme if existing or else set the default theme.
if(mode !== null){
// Set the mode
if(mode == "light"){
$(this).removeClass('fa-moon-o');
$(this).addClass('fa-sun-o');
daymode = $('.daymode').removeClass('daymode');
daymode.addClass('nightmode');
} else if(mode == "night") {
$(this).removeClass('fa-sun-o');
$(this).addClass('fa-moon-o');
nightmode = $('.nightmode').removeClass('nightmode');
nightmode.addClass('daymode');
}
} else {
// If no modes are selected. Define a default mode.
$(this).removeClass('fa-moon-o');
$(this).addClass('fa-sun-o');
daymode = $('.daymode').removeClass('daymode');
daymode.addClass('nightmode');
localStorage.setItem("theme", "light")
}
})
$('#toggleThemeMode').on('click', function() {
var mode = localStorage.getItem('theme');
if(mode !== null){
// Toggle the selected modes.
if(mode == "night"){
$(this).removeClass('fa-moon-o');
$(this).addClass('fa-sun-o');
daymode = $('.daymode').removeClass('daymode');
daymode.addClass('nightmode');
localStorage.setItem("theme", "light")
} else if(mode == "light") {
$(this).removeClass('fa-sun-o');
$(this).addClass('fa-moon-o');
nightmode = $('.nightmode').removeClass('nightmode');
nightmode.addClass('daymode');
localStorage.setItem("theme", "night")
}
} else {
// If no modes are selected. Define a default mode.
$(this).removeClass('fa-sun-o');
$(this).addClass('fa-moon-o');
nightmode = $('.nightmode').removeClass('nightmode');
nightmode.addClass('daymode');
localStorage.setItem("theme", "night")
}
};

Store CSS or HTML in localStorage

I have this function to toggle a dark mode on and of with a single button.
It checks if the dark.css stylesheet is already added to the site, if yes it removes it. If there isn't a dark.css it loads it and appends it to the head.
Now I want to store this information in the localStorage so the browser remembers whether the dark.css should be loaded or not.
$(function() {
$('#toggler').click(function(){
if ($('link[href*="css/dark.css"]').length) {
$('link[href*="css/dark.css"]').remove();
}
else {
var lightMode = document.createElement('link');
darkMode.rel="stylesheet";
darkMode.href="css/dark.css";
document.getElementsByTagName('head')[0].appendChild(darkMode);
}
});
})
All you have to do is check localStorage in your jQuery function. Preferably earlier in the function (so DOM is updated quickly in case you have some intensive code elsewhere), though not required.
$( function () {
function appendDarkMode() {
var darkMode = document.createElement( 'link' );
darkMode.rel = 'stylesheet';
darkMode.href = 'css/dark.css';
document.getElementsByTagName( 'head' )[ 0 ].appendChild( darkMode );
}
// This is run when page is first loaded.
if ( localStorage ) {
var useDarkMode = localStorage.getItem( 'useDarkMode' );
// The boolean we set in the click handler will become a string.
useDarkMode === 'true' ? appendDarkMode() : localStorage.setItem( 'useDarkMode', false );
}
// Theme click handler.
$( '.toggler' ).on( 'click', function ( e ) {
var $darkModeLink = $( 'link[href*="css/dark.css"]' );
$darkModeLink.length ? $darkModeLink.remove() : appendDarkMode();
if ( localStorage ) {
// Note that we're inverting the value here. By the time this
// is run, we will have changed whether or not `dark.css` is
// on the page. Which is opposite the initial value of
// `$darkModeLink`.
localStorage.setItem( 'useDarkMode', !$darkModeLink.length );
}
} );
} );
Although I don't think your approach is the best (loading this way could produce a 'flash' of improperly styled content depending on where you put your JS logic), here's my solution (not tested, but should work):
FYI: You'll want to check for localStorage availability or roll a pollyfill. See Mozilla Docs
$(function() {
var themes = {
light: 'light',
dark: 'dark'
};
var currentTheme = themes.light; // default to light
function changeTheme(theme) {
if (!theme || !themes[theme]) return;
setTheme(theme);
Object.keys(themes).forEach(function(t) {
var linkEl = $('link[href*="css/' + t + '.css"]');
if (linkEl.length && t !== theme) {
linkEl.remove();
}
});
}
function setTheme(theme) {
if (!theme || !themes[theme]) return;
var linkEl = document.createElement('link');
linkEl.rel="stylesheet";
linkEl.href="css/" + theme + ".css";
document.getElementsByTagName('head')[0].appendChild(linkEl);
if (localStorage) {
localStorage.setItem('theme', theme);
}
currentTheme = theme;
}
if (localStorage) {
var theme = localStorage.getItem('theme');
changeTheme(theme);
} else {
changeTheme(currentTheme);
}
$('#toggler').click(function(){
switch (currentTheme) {
case themes.light:
changeTheme(themes.dark);
break;
case themes.dark:
default:
changeTheme(themes.light);
break;
}
});
})

Categories