localStorage to save navbar state - javascript

I want to use localStorage to store the sidebar toggle so browser can remember the last toggle. Can someone please take a look at this code and tell me why it's not working?
$(document).ready(function() {
var sidebarshow = localStorage.getItem('sidebar') == 'true';
$('#sidebar').toggleClass('active', sidebar);
$("#toggle").click(function() {
$("#sidebar").toggleClass("slow",function() {
localStorage.setItem('sidebarshow', 'active');
});
$("#sidebar").toggleClass("active");
});
});
CSS
#sidebar.active {
position: fixed;
top: 0;
left: 0;
background: #1F6482;
width: 250px;
height: 100%;
color: #FFF;
}
#sidebar {
position: fixed;
top: 0;
left: 0;
background: #1F6482;
width: 75px;
height: 100%;
color: #FFF;
}

Problem: 1) you did not set the localStorage for key 'sidebar', But accessing will result into unexpected values.
var sidebarshow = localStorage.getItem('sidebar') == 'true';
Problem: 2) you are setting the localStorage for key 'sidebarshow', But you are not used any where. (at least in above code)
localStorage.setItem('sidebarshow', 'active');
Think of localStorage as a just object with key and values are of type string. Make sure to set the value first and get them later.
Here is sample code working.
$(document).ready(function() {
/*
if (window && window.localStorage.getItem('sidebar') === 'active') {
// if it active show it as active
$("#sidebar").addClass("active");
} else {
$("#sidebar").removeClass("active");
} */
$("#toggle").click(function() {
$("#sidebar").toggleClass("active");
var updated = '';
if (window.localStorage.getItem('sidebar') === 'active') {
updated = 'not_active';
} else {
updated = 'active';
}
window.localStorage.setItem('sidebar', updated);
});
});
#sidebar.active {
position: fixed;
top: 0;
left: 0;
background: #1F6482;
width: 250px;
height: 100%;
color: #FFF;
}
#sidebar {
position: fixed;
top: 0;
left: 0;
background: #1F6482;
width: 75px;
height: 100%;
color: #FFF;
}
#toggle {
margin-left: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sidebar"> Sidebar here </div>
<button id="toggle"> toggle </button>
Please check the screenshot of chrome debug console example with slightly changed to test.

If you're using the Admin-LTE v-3 package for front-end and wants to save the state of sidebar-collapse use this technique........ and an above solution is also working...
https://stackoverflow.com/a/59504461/8455396
Just read carefully and perform an action.
html tag hamburger button
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
<script>
$(document).ready(function() {
/*
check condition what value is stored in local storage if nothing then default
sidebar action would be performed you don't have to worry about this.
In Admin lte version 3 sidebar-collapse added in body tag inspect you browser and check
*/
if (window.localStorage.getItem('sidebar-toggle-collapsed') === 'false') {
// if it is off sidebar-collapse close
$("body").addClass("sidebar-collapse");
} else {
$("body").removeClass("sidebar-collapse");
}
// Perform click event action
$("[data-widget='pushmenu']").click(function() {
var buttonClickedValue = '';
if (window.localStorage.getItem('sidebar-toggle-collapsed') === 'false') {
buttonClickedValue = 'true';
} else {
buttonClickedValue = 'false';
}
// store value in local storage
window.localStorage.setItem('sidebar-toggle-collapsed', buttonClickedValue );
});
});
</script>

Related

I'm trying to open side panels with overlay and close

I'm trying to code my own Shopify theme and in that, I want to create different side panels (all coming in from the right) when someone clicks the panel link. I managed to get this to work with one panel and a script I found here on Stackoverflow (sorry I'm a complete newbie), but now I can't open different panels. Each link opens them all (obvious) but couldn't manage to trigger by the ID (my guess how to solve it) rather than the classes.
I would also like the overlay to close the panels. I only manage this by adding the toggle button into each panel.
My sidepanel script
<script>
$(document).ready(function() {
function toggleSidebar() {
$(".sidepanel-toggle").toggleClass("active");
$(".overlay").toggleClass("active");
$(".sidepanel").toggleClass("active");
$("body").toggleClass("activeoverlay");
}
$(".sidepanel-toggle").on("click tap", function() {
toggleSidebar();
});
$(document).keyup(function(e) {
if (e.keyCode === 27) {
toggleSidebar();
}
});
});
</script>
And the HTML for handling the panels
meta data
<aside id="extra_prod_meta" class="sidepanel">
meta data
</aside>
Brand
<aside id="extra_prod_brand" class="sidepanel">
meta data
</aside>
$body = $('body');
$('a.sidepanel-toggle').on('click', function(e) {
e.preventDefault();
let _this = $(this),
tg = _this.data('panel');
addActivePanel(tg,_this);
});
$('.close, .overlay').on('click', function(){
removeActivePanel();
});
function removeActivePanel(){
$body.removeClass('activeoverlay');
$('a.sidepanel-toggle, aside').removeClass('active');
}
function addActivePanel(panel,btn) {
$body.addClass('activeoverlay');
$('#'+panel).addClass('active');
btn.addClass('active');
}
aside {
box-sizing: border-box;
width: 200px;
height: 100%;
position: fixed;
top: 0;
right: -200px;
padding: 1rem;
background: #000;
color: #fff;
z-index: 2;
transition: right .3s ease;
}
aside.active {
right: 0;
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,.2);
z-index: -1;
display: none;
}
.activeoverlay .overlay {
display: block;
z-index: 1;
}
.close {
text-align: right;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
meta data
<div class="overlay"></div>
<aside id="extra_prod_meta" class="sidepanel">
<div class="close">X</div>
meta data extra_prod_meta
</aside>
Brand
<aside id="extra_prod_brand" class="sidepanel">
<div class="close">X</div>
meta data extra_prod_brand
</aside>
You could use data-attributes and target the correct panel.
$('a.sidepanel-toggle').on('click', function(e) {
e.preventDefault();
let _this = $(this),
tg = _this.data('panel');
$('#'+tg).addClass('active');
})
.active {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
meta data
<aside id="extra_prod_meta" class="sidepanel">
meta data
</aside>
Brand
<aside id="extra_prod_brand" class="sidepanel">
meta data
</aside>

Show logo if site has scrolled

I have a header with a logo. This logo should appear only if the site has been scrolled.
I tried this in javascript:
if(document.getElementById("div").scrollTop != 0){
document.write("<img src='logo.jpg'>");
}
But this did not work.
How to achieve it?
Use window.addEventListener('scroll', callback) and then set the value "block" to the img's property.
window.addEventListener('scroll', function(e) {
if (document.getElementsByTagName("html")[0].scrollTop > 5) {
document.getElementsByClassName('imgHeader')[0].style.display = "block";
} else {
document.getElementsByClassName('imgHeader')[0].style.display = "none";
}
});
.imgHeader {
height: 100px;
width: 100px;
display: none;
}
div {
height: 1000px;
}
header {
position: fixed;
top: 0;
width: 100%;
}
<header><img class="imgHeader" src="https://material.angular.io/assets/img/examples/shiba1.jpg" /></header>
<div></div>
Try this one
$(document).on("scroll", function() {
if ($(document).scrollTop() > 5) {
$(".below-top-header").addClass("show-class");
} else {
$(".below-top-header").removeClass("show-class");
}
});
.content {
height: 500px;
}
.show-class {
position: fixed;
display: block !important;
}
.hide-class {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
<div class="below-top-header hide-class">
Image
</div>
</div>
Unfortunately, I think you must use some JavaScript to make it work like you want.
Here is an easy snippet to show the principle I used:
Start with the logo already in the html, but with display: none in its CSS,
Use window.addEventListener('scroll', callback) to change display: none to display: block when the page is scrolled down (i.e. document.documentElement.scrollTop > 0).
var logo = document.getElementById('logo');
window.addEventListener('scroll', function(e) {
if (document.documentElement.scrollTop > 0) {
logo.style.display = 'block';
}else logo.style.display = 'none';
});
#logo {
display: none;
position: fixed;
top: 0;
background: #aaa;
}
#page {
background: #ddd;
height: 2000px;
}
<div id='logo'><img src='http://placekitten.com/200/50'></div>
<div id='page'>Start of page<br>Try to scroll down</div>
Hope it helps.
You need to add an scrollListener to the window in order to execute code when the user scrolls.
Your code only gets executed on page load.
Informations on Eventlisteners: https://developer.mozilla.org/de/docs/Web/API/EventTarget/addEventListener
window.addEventListener('scroll', function(e) {
//do something as soon as the window was scrolled
});
Be aware that the event will be triggered each time the user scrolls.

Dropdown menu open on hover instead of click on shopify

I'm trying to edit a shopify theme and the last part I'm stuck on is getting these navigation menus to open on hovering instead of clicking. The css I have for the menus is:
.site-nav {
position: relative;
padding: 0;
text-align: center;
margin: 25px 0;
a {
padding: 3px 10px;
}
li {
display: inline-block;
}
}
.site-nav--centered {
padding-bottom: $gutter-site-mobile;
}
/*================ Site Nav Links ================*/
.site-nav__link {
display: block;
white-space: nowrap;
.site-nav--centered & {
padding-top: 0;
}
.icon-chevron-down {
width: 8px;
height: 8px;
margin-left: 2px;
.site-nav--active-dropdown & {
transform: rotateZ(-180deg);
}
}
&.site-nav--active-dropdown {
border: 1px solid $color-border;
border-bottom: 1px solid transparent;
z-index: 2;
}
}
/*================ Dropdowns ================*/
.site-nav--has-dropdown {
position: relative;
}
.site-nav--has-centered-dropdown {
position: static;
}
.site-nav__dropdown {
display: none;
position: absolute;
left: 0;
padding: $dropdown-padding;
margin: 0;
z-index: $z-index-dropdown;
text-align: left;
border: 1px solid $color-border;
background: $color-bg;
left: -1px;
top: 41px;
.site-nav__link {
padding: 4px 30px 4px 0;
}
.site-nav--active-dropdown & {
display: block;
}
li {
display: block;
}
}
// Centered dropdown
.site-nav__dropdown--centered {
width: 100%;
border: 0;
background: none;
padding: 0;
text-align: center;
}
The HTML and Liquid for the header is:
{% if section.settings.align_logo == 'left' %}
<nav class="grid__item medium-up--one-half small--hide" id="AccessibleNav" role="navigation">
{% include 'site-nav' %}
</nav>
{% endif %}
And the relevant menu Javascript:
/* ================ MODULES ================ */
window.theme = window.theme || {};
theme.Header = (function() {
var selectors = {
body: 'body',
navigation: '#AccessibleNav',
siteNavHasDropdown: '.site-nav--has-dropdown',
siteNavChildLinks: '.site-nav__child-link',
siteNavActiveDropdown: '.site-nav--active-dropdown',
siteNavLinkMain: '.site-nav__link--main',
siteNavChildLink: '.site-nav__link--last'
};
var config = {
activeClass: 'site-nav--active-dropdown',
childLinkClass: 'site-nav__child-link'
};
var cache = {};
function init() {
cacheSelectors();
cache.$parents.on('click.siteNav', function(evt) {
var $el = $(this);
if (!$el.hasClass(config.activeClass)) {
// force stop the click from happening
evt.preventDefault();
evt.stopImmediatePropagation();
}
showDropdown($el);
});
// check when we're leaving a dropdown and close the active dropdown
$(selectors.siteNavChildLink).on('focusout.siteNav', function() {
setTimeout(function() {
if ($(document.activeElement).hasClass(config.childLinkClass) || !cache.$activeDropdown.length) {
return;
}
hideDropdown(cache.$activeDropdown);
});
});
// close dropdowns when on top level nav
cache.$topLevel.on('focus.siteNav', function() {
if (cache.$activeDropdown.length) {
hideDropdown(cache.$activeDropdown);
}
});
cache.$subMenuLinks.on('click.siteNav', function(evt) {
// Prevent click on body from firing instead of link
evt.stopImmediatePropagation();
});
}
function cacheSelectors() {
cache = {
$nav: $(selectors.navigation),
$topLevel: $(selectors.siteNavLinkMain),
$parents: $(selectors.navigation).find(selectors.siteNavHasDropdown),
$subMenuLinks: $(selectors.siteNavChildLinks),
$activeDropdown: $(selectors.siteNavActiveDropdown)
};
}
function showDropdown($el) {
$el.addClass(config.activeClass);
// close open dropdowns
if (cache.$activeDropdown.length) {
hideDropdown(cache.$activeDropdown);
}
cache.$activeDropdown = $el;
// set expanded on open dropdown
$el.find(selectors.siteNavLinkMain).attr('aria-expanded', 'true');
setTimeout(function() {
$(window).on('keyup.siteNav', function(evt) {
if (evt.keyCode === 27) {
hideDropdown($el);
}
});
$(selectors.body).on('click.siteNav', function() {
hideDropdown($el);
});
}, 250);
}
function hideDropdown($el) {
// remove aria on open dropdown
$el.find(selectors.siteNavLinkMain).attr('aria-expanded', 'false');
$el.removeClass(config.activeClass);
// reset active dropdown
cache.$activeDropdown = $(selectors.siteNavActiveDropdown);
$(selectors.body).off('click.siteNav');
$(window).off('keyup.siteNav');
}
function unload() {
$(window).off('.siteNav');
cache.$parents.off('.siteNav');
cache.$subMenuLinks.off('.siteNav');
cache.$topLevel.off('.siteNav');
$(selectors.siteNavChildLink).off('.siteNav');
$(selectors.body).off('.siteNav');
}
return {
init: init,
unload: unload
};
})();
Any help would be greatly appreciated. I feel so silly asking a simple question like this. I just can't figure out where to put :hover in the code. It seems pretty strait forward but I can't get it. You can see the site here: AlexandIvy.myShopify.com and the password to view it is staysk. I'm just talking about the top navigation menus.
This is the code from the console:
<nav class="grid__item medium-up--one-half small--hide" id="AccessibleNav" role="navigation">
<ul class="site-nav list--inline " id="SiteNav">
<li class="site-nav--has-dropdown">
<a href="/collections/bedding" class="site-nav__link site-nav__link--main" aria-has-popup="true" aria-expanded="false" aria-controls="SiteNavLabel-bedding">
Bedding
<svg aria-hidden="true" focusable="false" role="presentation" class="icon icon--wide icon-chevron-down" viewBox="0 0 498.98 284.49"><defs><style>.cls-1{fill:#231f20}</style></defs><path class="cls-1" d="M80.93 271.76A35 35 0 0 1 140.68 247l189.74 189.75L520.16 247a35 35 0 1 1 49.5 49.5L355.17 511a35 35 0 0 1-49.5 0L91.18 296.5a34.89 34.89 0 0 1-10.25-24.74z" transform="translate(-80.93 -236.76)"></path></svg>
<span class="visually-hidden">expand</span>
</a>
<div class="site-nav__dropdown" id="SiteNavLabel-bedding">
<ul>
<li>
Sheet Sets
</li>
</ul>
</div>
</li>
Since you're using JS to hide/show the dropdowns, I suggest you do this if you're comfortable with JQuery.
$('.site-nav--has-dropdown').hover(function() {
if ($(this).hasClass('activated')){
$(this).removeClass('activated');
$(this).children('.site-nav__dropdown').css('display', 'none');
}
else{
$(this).addClass('activated');
$(this).children('.site-nav__dropdown').css('display', 'block');
}
});
The idea behind this is that the child closest to .site-nav--has-dropdown which has a class name .site-nav__dropdown can be activated on hover. You can use pol's code too which provides a different (and shorter) approach.
You should use mouseover/mouseout methods in jquery.
$('.site-nav--has-dropdown').mouseover(function() {
$(this).children('.site-nav__dropdown').show();
});
$('.site-nav--has-dropdown').mouseout(function() {
$(this).children('.site-nav__dropdown').hide();
});
Or just use css :hover,
to better support touch devices you should add :focus too.
.site-nav--has-dropdown:hover .site-nav__dropdown,
.site-nav--has-dropdown:focus .site-nav__dropdown {
display: block;
}
jsfiddle demo: sfiddle.net/8p33qh9h

Light box pop up form in jquery

Here is my code:
Please fill out my form.
<script>
var test = document.getElementById('test');
var win = null;
test.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
win = window.open(test.href, null, 'height=823, width=680, toolbar=0, location=0, status=1, scrollbars=1, resizable=1');
return false;
});
window.addEventListener('click', function(e) {
if(win != null) {
win.close();
win = null;
}
});
</script>
This code works fine, but i need like to display as light box, for example please refer this site, http://fancybox.net/ ,, I am new to javascript, can anyone one help me to do this,
Any help would be appreciated, Thank you.
To start working with javascript, you would need a javascript library API. You must have heard about JQuery, this makes your work easier than regular Javascript codes. JQuery have lots of plugins especially for lightbox gallery that you are looking for. One useful lightbox plugin is Colorbox.
Start by importing the libraries to your header just like below. You also might need some css files for the colorbox themes.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
<script src="../jquery.colorbox.js"></script>
Then start using colorbox just like below
Please fill out my form.
$(document).ready(function(){
$("#test").click(function(){ //on clicking the link above
$(this).colorbox({ //this would capture the url from the href
width:'500px', //width of the colorbox
height:'auto', //height of the colorbox
initialWidth:'500px', //initial width upon loading
initialHeight:'auto', //initial height upon loading
speed:0, //animation speed
opacity:0.2, //background opacity
overlayClose: true, //close upon clicking anywhere
title:'Your Form Title', //your form title name
onComplete: function(){
//do something when the colorbox loaded completely
}
});
})
});
Take a look on this following example. This is custom light box without any plugin:
Updated Fiddle
jQuery:
var lightBox = $('#lightbox'),
lightBoxContent = $('#lb-content');
var positionLightbox = function() {
var veiwWidth = $(window).width(),
lbContentMargin = (veiwWidth / 2) - 148,
lbContent = $('#lb-content');
lbContent.css({
'left' : lbContentMargin,
'top' : $(window).scrollTop() + 50 + 'px'
});
};
$('#test').click(function(e) {
e.preventDefault();
lightBox.fadeIn(function() {
lightBoxContent.show();
});
positionLightbox();
});
$('#lb-close').click(function() {
lightBox.hide();
lightBoxContent.hide();
});
/*hide click outside*/
$(document).mouseup(function (e)
{
if (!lightBoxContent.is(e.target) // if the target of the click isn't the container...
&& lightBoxContent.has(e.target).length === 0) // ... nor a descendant of the container
{
lightBox.hide();
lightBoxContent.hide();
}
});
CSS:
body {color: #fff; font-family: arial; font-family: arial;}
#lightbox {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.8;
text-align: center;
display: none;
}
#lb-content {
color: #222;
height: 150px;
width: 260px;
border: 16px solid #222;
background-color: #fff;
position: relative;
text-align: center;
padding-top: 10px;
border-radius: 4px;
display: none;
}
#lb-close {
display: block;
height: 22px;
width: 25px;
background-color: red;
color: #fff;
position: absolute;
top: -25px;
right: -25px;
cursor: pointer;
text-align: center;
border-radius: 10px;
}
You can go for jQuery Plugin also:
http://lokeshdhakar.com/projects/lightbox2/
http://dimsemenov.com/plugins/magnific-popup/
http://www.jacklmoore.com/colorbox/

How to toggle (hide / show) sidebar div using jQuery

I have 2 <div>s with ids A and B. div A has a fixed width, which is taken as a sidebar.
The layout looks like diagram below:
The styling is like below:
html, body {
margin: 0;
padding: 0;
border: 0;
}
#A, #B {
position: absolute;
}
#A {
top: 0px;
width: 200px;
bottom: 0px;
}
#B {
top: 0px;
left: 200px;
right: 0;
bottom: 0px;
}
I have <a id="toggle">toggle</a> which acts as a toggle button. On the toggle button click, the sidebar may hide to the left and div B should stretch to fill the empty space. On second click, the sidebar may reappear to the previous position and div B should shrink back to the previous width.
How can I get this done using jQuery?
$('button').toggle(
function() {
$('#B').css('left', '0')
}, function() {
$('#B').css('left', '200px')
})
Check working example at http://jsfiddle.net/hThGb/1/
You can also see any animated version at http://jsfiddle.net/hThGb/2/
See this fiddle for a preview and check the documentation for jquerys toggle and animate methods.
$('#toggle').toggle(function(){
$('#A').animate({width:0});
$('#B').animate({left:0});
},function(){
$('#A').animate({width:200});
$('#B').animate({left:200});
});
Basically you animate on the properties that sets the layout.
A more advanced version:
$('#toggle').toggle(function(){
$('#A').stop(true).animate({width:0});
$('#B').stop(true).animate({left:0});
},function(){
$('#A').stop(true).animate({width:200});
$('#B').stop(true).animate({left:200});
})
This stops the previous animation, clears animation queue and begins the new animation.
You can visit w3school for the solution on this the link is here and there is another example also available that might surely help,
Take a look
The following will work with new versions of jQuery.
$(window).on('load', function(){
var toggle = false;
$('button').click(function() {
toggle = !toggle;
if(toggle){
$('#B').animate({left: 0});
}
else{
$('#B').animate({left: 200});
}
});
});
Using Javascript
var side = document.querySelector("#side");
var main = document.querySelector("#main");
var togg = document.querySelector("#toogle");
var width = window.innerWidth;
window.document.addEventListener("click", function() {
if (side.clientWidth == 0) {
// alert(side.clientWidth);
side.style.width = "200px";
main.style.marginLeft = "200px";
main.style.width = (width - 200) + "px";
togg.innerHTML = "Min";
} else {
// alert(side.clientWidth);
side.style.width = "0";
main.style.marginLeft = "0";
main.style.width = width + "px";
togg.innerHTML = "Max";
}
}, false);
button {
width: 100px;
position: relative;
display: block;
}
div {
position: absolute;
left: 0;
border: 3px solid #73AD21;
display: inline-block;
transition: 0.5s;
}
#side {
left: 0;
width: 0px;
background-color: red;
}
#main {
width: 100%;
background-color: white;
}
<button id="toogle">Max</button>
<div id="side">Sidebar</div>
<div id="main">Main</div>
$('#toggle').click(function() {
$('#B').toggleClass('extended-panel');
$('#A').toggle(/** specify a time here for an animation */);
});
and in the CSS:
.extended-panel {
left: 0px !important;
}
$(document).ready(function () {
$(".trigger").click(function () {
$("#sidebar").toggle("fast");
$("#sidebar").toggleClass("active");
return false;
});
});
<div>
<a class="trigger" href="#">
<img id="icon-menu" alt='menu' height='50' src="Images/Push Pin.png" width='50' />
</a>
</div>
<div id="sidebar">
</div>
Instead #sidebar give the id of ur div.
This help to hide and show the sidebar, and the content take place of the empty space left by the sidebar.
<div id="A">Sidebar</div>
<div id="B"><button>toggle</button>
Content here: Bla, bla, bla
</div>
//Toggle Hide/Show sidebar slowy
$(document).ready(function(){
$('#B').click(function(e) {
e.preventDefault();
$('#A').toggle('slow');
$('#B').toggleClass('extended-panel');
});
});
html, body {
margin: 0;
padding: 0;
border: 0;
}
#A, #B {
position: absolute;
}
#A {
top: 0px;
width: 200px;
bottom: 0px;
background:orange;
}
#B {
top: 0px;
left: 200px;
right: 0;
bottom: 0px;
background:green;
}
/* makes the content take place of the SIDEBAR
which is empty when is hided */
.extended-panel {
left: 0px !important;
}

Categories

Resources