problem with the sidebar. sidebar is not closing - javascript

for some reason the close button on the sidebar is not showing nor working, the show sidebar works perfectly fine however the closing function is not working. im providing the html, css ans javascript related to the close function
here's my html:
<aside class="sidenav">
<div class="sidenav__close-icon">
<i class="bi bi-x-lg"></i>
</div>
<img class="sidenav__logo" src="../static/img/ManageX5.png">
<ul class="sidenav__list">
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('dashboard')}}">Dashboard</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('profile')}}">Profile</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('users')}}">Users</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('projects')}}">Projects</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('sites')}}">Sites</a>
</li>
</ul>
<ul class="sidenav__logout">
<li class="list-logout-item">
<a class="sidenav__list-item-logout" href="#">logout</a>
</li>
</ul>
</aside>
this is the JS part:
const menuIconEl = $('.menu-icon');
const sidenavEl = $('.sidenav');
const sidenavCloseEl = $('.sidenav__close-icon');
/*===== Add and remove provided class names =====*/
function toggleClassName(el, className) {
if (el.hasClass(className)) {
el.removeClass(className);
} else {
el.addClass(className);
}
}
/*===== Open the side nav on click =====*/
menuIconEl.on('click', function() {
toggleClassName(sidenavEl, 'active');
});
/*===== Close the side nav on click =====*/
sidenavCloseEl.on('click', function() {
toggleClassName(sidenavEl, 'active');
});
and this is the css related to the sidebar:
.sidenav__close-icon {
position: absolute;
visibility: visible;
top: 8px;
right: 12px;
cursor: pointer;
font-size: 20px;
color: #000;
}

The reason of why you can't see the close icon isn't showing up is that you don't have the necessary styles that makes the element (.sidenav__close-icon) to be rendered/shown as an icon.
If you have it somewhere in your project, I suggest you making some tweaks like the following:
You can use jQuery's toggleClass method to toggle a class
function toggleClassName(el, className) {
el.toggleClass(className);
}
The close button/icon has CSS properties (position, top, right) that makes it positioned to top right of the page which results in not visible. You may have to add the following CSS in order to give close icon a relative position. In your case, the relativity can be inherited from its parent, the .sidenav element.
.sidenav {
position: relative;
width: 200px;
}
.sidenav__close-icon {
position: absolute;
visibility: visible;
top: 8px;
right: 12px;
cursor: pointer;
font-size: 20px;
color: #000;
}
Here's a snippet which toggles active class and demonstrates the change
const menuIconEl = $('.menu-icon');
const sidenavEl = $('.sidenav');
const sidenavCloseEl = $('.sidenav__close-icon');
/*===== Add and remove provided class names =====*/
function toggleClassName(el, className) {
el.toggleClass(className);
// Much shorter, but the following lines can also work
/*if (el.hasClass(className)) {
el.removeClass(className);
} else {
el.addClass(className);
}*/
}
/*===== Open the side nav on click =====*/
menuIconEl.on('click', function () {
toggleClassName(sidenavEl, 'active');
});
/*===== Close the side nav on click =====*/
sidenavCloseEl.on('click', function () {
toggleClassName(sidenavEl, 'active');
});
.sidenav {
position: relative;
width: 200px;
}
.sidenav__close-icon {
position: absolute;
visibility: visible;
top: 8px;
right: 12px;
cursor: pointer;
font-size: 20px;
color: #000;
}
.active {
outline: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<aside class="sidenav">
<div class="sidenav__close-icon">
<i class="bi bi-x-lg">X</i>
</div>
<img class="sidenav__logo" src="../static/img/ManageX5.png">
<ul class="sidenav__list">
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('dashboard')}}">Dashboard</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('profile')}}">Profile</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('users')}}">Users</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('projects')}}">Projects</a>
</li>
<li class="sidenav__list-item">
<a class="sidenav__list-item-items" href="{{url_for('sites')}}">Sites</a>
</li>
</ul>
<ul class="sidenav__logout">
<li class="list-logout-item">
<a class="sidenav__list-item-logout" href="#">logout</a>
</li>
</ul>
</aside>

Related

Sidebar animation keeps playing on load

Have a sidebar on my website but when I load the page it plays the animation of it closing. how would I stop this?
I have a class #sidebar thats the class in its normal state and a class active that makes it move out
#sidebar {
margin-left: -250px;
width: 250px;
position: fixed;
top: 0;
left: 0;
height: 100vh;
z-index: 0;
background: #222222;
color: #fff;
transition: 0.3s;
visibility: hidden;
}
#sidebar.active {
width: 250px;
margin-left: 0px;
transition: 0.3s;
z-index: 999;
visibility: visible;
}
Javascript for changing the active class
$(document).ready(function () {
$("#sidebar").mCustomScrollbar({
theme: "minimal"
});
$('#sidebarCollapse').on('click', function () {
$('#sidebar, #content').toggleClass('active');
$('.collapse.in').toggleClass('in');
$('a[aria-expanded=true]').attr('aria-expanded', 'false');
});
});
UPDATE
Html code for the sidebar. if it helps I am using mustache js for templating if that is of importance to this
<!-- Sidebar -->
<nav id="sidebar">
<div class="sidebar-header">
<h3>Admin Panel</h3>
</div>
<ul class="list-unstyled components">
<p>Admin controls</p>
<li>
Menu's
<ul class="collapse list-unstyled" id="menuSubmenu">
<li>
Add
</li>
<li>
Edit
</li>
</ul>
</li>
<li>
Categories
<ul class="collapse list-unstyled" id="catSubmenu">
<li>
Add
</li>
<li>
Edit
</li>
</ul>
</li>
<li>
Dish's
<ul class="collapse list-unstyled" id="dishSubmenu">
<li>
Add
</li>
<li>
Edit
</li>
</ul>
</li>
<li>
Staff
<ul class="collapse list-unstyled" id="staffSubmenu">
<li>
Register
</li>
<li>
Delete
</li>
</ul>
</li>
<li>
Site settings
</li>
<li>
<a id="logout" href="/logout" class="btn btn-primary">Sign out</a>
</li>
</ul>
</nav>
Can you try below CSS
#sidebar {
position: absolute;
top: 0;
left: -250px;
bottom: 0;
width: 250px;
height: 100vh;
z-index: 999;
background: #222222;
color: #fff;
transition: 0.3s;
}
#sidebar.active {
left: 0;
}
Plus you have to pass active class to your sidebar also if you want to be active by default
<nav id="sidebar" class="active">

how to add active class on click and prevent the submenu from sliding up

I am trying to add/ remove active class and prevent my submenu from sliding up when active. If i click on specific tab, it should be active until i switch to another tab. Have tried with addclass/ removeclass, but no change in html onclick. Could anyone suggest how to achieve this.
when submenu 'akun belanja' is active
when i click any of the submenu it will remove the active status and slide up ,like this:
clicked 'daftar akun belanja'
my sidebar:
<nav id="sidebar">
<div class="sidebar-header">
<div class="p-b-13">
<img src="{{url('/asset/login/images/itk.png')}}" alt="itk" class="center">
</div>
<h6 align="center">Sistem Informasi</h6>
<h3 class="h3_sidebar" align="center" style="color:#0067B2">MANAJEMEN</h3>
</div>
<ul class="list-unstyled components">
<li>
SPJ dan LPJ <i class="fa fa-caret-down float-right mr-2"></i>
<ul class="collapse list-unstyled" id="homeSubmenu">
<li>
Surat Pertanggung Jawaban
</li>
<li>
Laporan Pertanggung Jawaban
</li>
</ul>
</li>
<li>
Akun Belanja <i class="fa fa-caret-down float-right mr-2"></i>
<ul class="collapse list-unstyled" id="pageSubmenu">
<li>
Daftar Akun Belanja
</li>
<li>
Panduan Akun Belanja
</li>
</ul>
</li>
<li>
Help
</li>
<li>
Contact
</li>
</ul>
</nav>
js:
<script>
$(document).ready(function () {
$(".ul .a").on("click", function () {
$(".ul").find(".active").removeClass("active");
$(this).addClass("active");
});
});
</script>
There are a few things here:
your CSS is missing in the code, so I have to make a few assumptions
when you navigate in jQuery, you use .ul where you should use ul. Similar for .a and a.
I have documented in the source itself.
$(document).ready(function() {
$("ul li > a").on("click", function() {
$("ul").find(".active").removeClass("active");
$(this).addClass("active");
$("ul").find("ul").css("display", "none"); /* close submenu */
$(this).next("ul").css("display", "block"); /*display submenu */
});
});
/* default link color */
a {
color: purple;
}
/* color for active link */
a.active {
color: red;
}
/* hide submenu's by default */
ul>li>ul {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav id="sidebar">
<div class="sidebar-header">
<div class="p-b-13">
<img src="" alt="itk" class="center">
</div>
<h6 align="center">Sistem Informasi</h6>
<h3 class="h3_sidebar" align="center" style="color:#0067B2">MANAJEMEN</h3>
</div>
<ul class="list-unstyled components">
<li>
SPJ dan LPJ <i class="fa fa-caret-down float-right mr-2"></i>
<ul class="collapse list-unstyled" id="homeSubmenu">
<li>
Surat Pertanggung Jawaban
</li>
<li>
Laporan Pertanggung Jawaban
</li>
</ul>
</li>
<li>
Akun Belanja <i class="fa fa-caret-down float-right mr-2"></i>
<ul class="collapse list-unstyled" id="pageSubmenu">
<li>
Daftar Akun Belanja
</li>
<li>
Panduan Akun Belanja
</li>
</ul>
</li>
<li>
Help
</li>
<li>
Contact
</li>
</ul>
</nav>
Fixing of your jQuery function:
Update all .ul to ul AND .a to a becuase it is not class, it is TAG.
<script>
$(document).ready(function () {
$("ul a").on("click", function () {
$("ul").find(".active").removeClass("active");
$(this).addClass("active");
});
});
</script>
Working sample is as below
If you are going to use a perfect sample side navigation with dropdown feature, Plesae refer to the code below. It should works. It is in JavaScript. You can merge with jQuery if you want.
/* Loop through all dropdown buttons to toggle between hiding and showing its dropdown content - This should avoid conflict. */
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() {
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
});
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {
font-family: "Lato", sans-serif;
}
/* Fixed sidenav, full height */
.sidenav {
height: 100%;
width: 200px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
padding-top: 20px;
}
/* Style the sidenav links and the dropdown button */
.sidenav a, .dropdown-btn {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 20px;
color: #818181;
display: block;
border: none;
background: none;
width: 100%;
text-align: left;
cursor: pointer;
outline: none;
}
/* On mouse-over */
.sidenav a:hover, .dropdown-btn:hover {
color: #f1f1f1;
}
/* Main content */
.main {
margin-left: 200px; /* Same as the width of the sidenav */
font-size: 20px; /* Increased text to enable scrolling */
padding: 0px 10px;
}
/* Add an active class to the active dropdown button */
.active {
background-color: orange;
color: white;
}
/* Dropdown container (hidden by default). Optional: add a lighter background color and some left padding to change the design of the dropdown content */
.dropdown-container {
display: none;
background-color: #262626;
padding-left: 8px;
}
/* Optional: Style the caret down icon */
.fa-caret-down {
float: right;
padding-right: 8px;
}
/* Some media queries for responsiveness */
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
</style>
</head>
<body>
<div class="sidenav">
About
Services
Clients
Contact
<button class="dropdown-btn">Dropdown
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-container">
Link 1
Link 2
Link 3
</div>
Search
</div>
<div class="main">
<h2>Sidebar Dropdown</h2>
<p>Click on the dropdown button to open the dropdown menu inside the side navigation.</p>
<p>This sidebar is of full height (100%) and always shown.</p>
<p>Some random text..</p>
</div>
</body>
</html>

Make the background image of class to be slideshow

I have class that have background image and this background image have fixed navbar and some text on it. How can I make this background image to be slideshow with another two images. Can someone help me with this without damaging the fixed navbar and the text on it?
Here is my codes
<div id="home" class="intro route bg-image" >
<nav class="navbar navbar-b navbar-trans navbar-expand-md fixed-top" id="mainNav">
<div class="container">
<a class="navbar-brand js-scroll" href="#page-top"><%= image_tag "logo.png",class: "logo",alt: "eric chism trail to welness logo" %></a>
<button class="navbar-toggler collapsed" type="button" data-toggle="collapse" data-target="#navbarDefault"
aria-controls="navbarDefault" aria-expanded="false" aria-label="Toggle navigation">
<span></span>
<span></span>
<span></span>
</button>
<div class="navbar-collapse collapse justify-content-end" id="navbarDefault">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link js-scroll active" href="#home">Home</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#about">About</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#service">Services</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#work">Portfolio</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#contact">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="overlay-itro"></div>
<div class="intro-content display-table">
<div class="table-cell">
<div class="container">
<h1 class="intro-title mb-4">Eric Chism Trail to Wellness</h1>
<p class="intro-subtitle"> provides a customized journey to complete health and wellness</span><strong class="text-slider"></strong></p>
<!-- <p class="pt-3"><a class="btn btn-primary btn js-scroll px-4" href="#about" role="button">Learn More</a></p> -->
</div>
</div>
</div>
</div>
css file
.intro {
height: 100vh;
position: relative;
color: #fff;
background-image: url(asset-path("attachment_1550437745.png"));
}
.intro .intro-content {
text-align: center;
position: absolute;
}
I have created a very raw, pure CSS solution, as good starting point for you. Using different animations and delays you could achieve some really awesome effects.
body {
margin: 0;
padding: 0;
}
.route {
height: 100vh;
position: relative;
color: #fff;
}
.navbar {
position: fixed;
}
.slide {
position: relative;
height: 100%;
width: 33.33%;
margin: 0;
float: left;
}
.slide-1 {
background-image: url(https://picsum.photos/1200/800?image=11);
}
.slide-2 {
background-image: url(https://picsum.photos/1200/800?image=12);
}
.slide-3 {
background-image: url(https://picsum.photos/1200/800?image=13);
}
.slideshow {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 0;
overflow: hidden;
color: #000;
}
.slideshow-inner {
position: relative;
height: 100%;
width: 300%;
animation: move 20s ease infinite;
}
.intro .intro-content {
text-align: center;
position: absolute;
}
#keyframes move {
0% {
transform: translate(0, 0);
}
33.33% {
transform: translate(-33.33%, 0);
}
66.66% {
transform: translate(-66.66%, 0);
}
}
<div id="home" class="route bg-image">
<div class="slideshow">
<div class="slideshow-inner">
<div class="slide slide-1"><span>Some Text</span></div>
<div class="slide slide-2"><span>Some Text</span></div>
<div class="slide slide-3"><span>Some Text</span></div>
</div>
</div>
<nav class="navbar navbar-b navbar-trans navbar-expand-md fixed-top" id="mainNav">
<div class="container">
<div class="navbar-collapse collapse justify-content-end" id="navbarDefault">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link js-scroll active" href="#home">Home</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#about">About</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#service">Services</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#work">Portfolio</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll" href="#contact">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
</div>
Presumably you mean a time-based slideshow rather than one where the user presses buttons. The various options are all typically handled with JavaScript. As your background element has children, I would extend your existing code by adding new classes corresponding to new background images, and switching between them.
.bg1 {
background-image: url(asset-path("img1.png"));
}
.bg2 {
background-image: url(asset-path("img2.png"));
}
.bg3 {
background-image: url(asset-path("img3.png"));
}
Then add the first class to your background element:
<div id="home" class="intro route bg-image bg1" >
and include JS code to cycle through the classes, like below - included as part of a snippet so you can see the effect.
function updateSlide() {
const bgCount = 3; //This needs to match the number of background classes - main weakness of this snippet
const bgElem = document.getElementById('home'); // Background element
let foundClasses = []; //List of background classes found
let bgIndex = 0;
for(let classIndex = 0; classIndex < bgElem.classList.length; classIndex++) { // Using a full for in case the element somehow gets multiple background classes
const thisClass = bgElem.classList.item(classIndex);
if(thisClass.substr(0, 2) == 'bg') {
foundClasses += thisClass;
bgIndex = parseInt(thisClass.substr(2)) + 1;
}
}
if(bgIndex > bgCount) {
bgIndex = 1;
}
bgElem.classList.add('bg' + bgIndex); //Apply the new class
bgElem.classList.remove(foundClasses); //Remove all previous background classes
}
setInterval(updateSlide, 2000); // Change every 2 seconds
#home {
display: block;
}
.bg1 {
background: red;
}
.bg2 {
background: yellow;
}
.bg3 {
background: green;
}
<div id="home" class="bg1">Test</div>
Long-term, you would want the cycling script to get its background-count from a Rails variable or the HTML instead of a hard-coded value.

<nav> element moves out of parent when having <a> element as a child

So I was modifying HTML to make drop down panels in order to minimize use of JavaScript.
.nav-link {
border: 1px solid black;
margin: 10px;
text-decoration: none;
}
.panel-link {
display: none;
position: absolute;
}
.nav-link:hover .panel-link {
display: block;
}
<nav class="nav">
<a href="withoutchild.html" class="nav-link">
<span>Without Child</span>
<nav class="panel-link">
<h1>Works</h1>
</nav>
</a>
<a href="withchild.html" class="nav-link">
<span>With Child</span>
<nav class="panel-link">
<a>Not Works</a>
</nav>
</a>
</nav>
When you hover both of them, you notice that only the first link opens its drop down panel when you hover it. However, with the second link (Which was layed out exactly the same), it did not because it had a link element as the child. When I view the inspector of Chrome, I realized the '.panel-link' element moved out of the '.nav-link' element, and is now a sibling of '.nav-link'. which looked just like this:
<nav class="nav">
<a href="withoutchild.html" class="nav-link">
<span>Without Child</span>
<nav class="panel-link">
<h1>Works</h1>
</nav>
</a>
<a href="withchild.html" class="nav-link">
<span>With Child</span>
</a>
<!-- This element is moved outside its parent -->
<nav class="panel-link">
<a>Not Works</a>
</nav>
</nav>
Nested <a> (anchor tags) are illegal and result in unrecoverable errors.
In plain English, browsers ignore all contents of the nested <a>, until they meet the end of this tag (</a>), which they use to close the parent <a> tag.
Use the HTML validator of your choice for more details. I use nu.
I think the issue is that you have an <a> tag within a parent <a> tag.
I'm not sure what you wanted the <h1> text/link to look like so kept it in anyway. Using CSS, hovering a div can reveal another div.
.panel-link {
border: 1px solid black;
margin: 10px;
text-decoration: none;
}
.nav-link {
position: relative;
display: inline-block;
}
.nav-link-content {
display: none;
position: absolute;
z-index: 1;
}
.nav-link-content a {
color: black;
padding: 2px 16px;
display: block;
}
.nav-link-content a:hover {
background-color: #fff000
}
.nav-link:hover .nav-link-content {
display: block;
}
<nav class="nav">
<div class="nav-link">
<span>Without Child</span>
<div class="nav-link-content">
<h1>Works</h1>
</div>
</div>
<div class="nav-link">
<span>With Child</span>
<div class="nav-link-content">
Child 1
Child 2
Child 3
</div>
</div>
</nav>

using .trigger to pass event to child [duplicate]

This question already has answers here:
Trigger click jquery not working
(4 answers)
Closed 6 years ago.
I am trying to pass a click event on parent li element to its child a.
following is the code I have tried, which does not seem to work. Where did i go wrong? and what is the best way to achieve this.
EDIT I understand I can restyle my a elements and get myself completely out of this situation. But I want to know why the bellow code is not working and what is a propper way to achive this kind of passing of events.
$('.menuItem').click(function() {
$(this).children('a').trigger('click');
});
ul {
list-style: none;
padding: 0px;
position: relative;
z-index: 1000;
display: inline-block;
background-color: white;
height: 30px;
}
ul li {
display: inline-block;
padding: 20px;
margin-right: 0px;
font-weight: 500;
background-color: white;
cursor: pointer;
}
ul li:hover {
background-color: red;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="menuItem">
<a href="www.google.com">
Home
</a>
</li>
<li class="menuItem">
<a href="www.google.com">
About
</a>
</li>
<li class="menuItem">
<a href="www.google.com">
News
</a>
</li>
<li class="menuItem">
<a href="www.google.com">
Gallery
</a>
</li>
<li class="menuItem">
<a href="www.google.com">
Media
</a>
</li>
<li class="menuItem">
<a href="www.google.com">
Contact
</a>
</li>
</ul>
Why not do it this way?
$('.menuItem').click(function() {
var href = $('a', this).attr('href');
window.location.href = href; //causes the browser to refresh and load the requested url
});

Categories