Hide Collapse Menu & Toggle Menu in Angular - javascript

I found a problem, how do I do that when the user clicks on one of the dropdown menus on the mobile, it will close the previous dropdown menu and open the clicked menu? Then when the user click a menu inside the dropdown, it will close all dropdown menus including the toggle menu?
Here's the code I have
ngOnInit(): void {
if ($(window).width() < 991.98) {
document.querySelectorAll('.nav-item').forEach(function(element){
element.addEventListener('click', function (this: any, e) {
let nextEl = this.nextElementSibling;
if(nextEl && nextEl.classList.contains('dropdown-menu')) {
e.preventDefault();
if(nextEl.style.display == 'block'){
nextEl.style.display = 'none';
nextEl.style.opacity = '0';
nextEl.style.position = 'relative';
$(this).closest('li').removeClass('active');
} else {
nextEl.style.display = 'block';
nextEl.style.opacity = '1';
nextEl.style.position = 'relative';
$(this).closest('li').addClass('active');
}
}
});
})
}
}
collapse() {
this.showMenu = !this.showMenu;
var toggle;
if (this.showMenu == true) {
toggle = this.elRef.nativeElement.querySelector('.toggle-menu');
toggle.classList.add('active');
$('.header-area .nav').slideToggle(200);
} else {
toggle = this.elRef.nativeElement.querySelector('.toggle-menu');
toggle.classList.remove('active');
$('.header-area .nav').slideToggle(200);
}
}
index.html
<ul class="nav">
<li>
<a class="nav-item">Home</a>
<div class="dropdown-menu">
<a routerLink="/home" class="dropdown-item">Home</a>
<a routerLink="/dashboard" class="dropdown-item">Dashboard</a>
<a routerLink="/setting" class="dropdown-item">Setting</a>
</div>
</li>
<li>
<a class="nav-item">Explore</a>
<div class="dropdown-menu">
<a routerLink="/user" class="dropdown-item">User</a>
<a routerLink="/admin" class="dropdown-item">Admin</a>
</div>
</li>
</ul>
<a class="toggle-menu" (click)="collapse()">
<span>Menu</span>
</a>

First, I would say that you should not using JQuery and some basic Javascript document query syntaxs in Angular. Angular is not working like this.
Second, about the dropdown, thinking more simple, you need to determine which button was pressed, add class "active" if it not already there, and remove from all remaining

Related

Collapsible List - Need to make a collapse all button

I am working on making an unordered list collapsible. I have created a hamburger/ collapsible/ accordian menu already. However, I want to add a "Expand All/ Collapse All" button on the top. Can someone help me with the code?
function expandCollapse() {
var theHeaders = document.querySelectorAll('.expandCollapse h2'),
i;
for (i = 0; i < theHeaders.length; i++) {
var thisEl = theHeaders[i],
theId = 'panel-' + i;
var thisTarget = thisEl.parentNode.querySelector('.panel');
if (!thisTarget) {
continue;
}
// Create the button
thisEl.innerHTML = '<button aria-expanded="false" aria-controls="' + theId + '">' + thisEl.textContent + '</button>';
// Create the expandable and collapsible list and make it focusable
thisTarget.setAttribute('id', theId);
thisTarget.setAttribute('hidden', 'true');
}
// Make it click
var theButtons = document.querySelectorAll('.expandCollapse button[aria-expanded][aria-controls]');
for (i = 0; i < theButtons.length; i++) {
theButtons[i].addEventListener('click', function(e) {
var thisButton = e.target;
var state = thisButton.getAttribute('aria-expanded') === 'false' ? true : false;
thisButton.setAttribute('aria-expanded', state);
document.getElementById(thisButton.getAttribute('aria-controls')).toggleAttribute('hidden', !state);
});
}
}
expandCollapse();
<div class="expandCollapse">
<section id="teams">
<h2>Fruits</h2>
<div class="panel">
<ul>
<li>
Mango
</li>
</ul>
</div>
</section>
<section>
<h2>Ghadarite</h2>
<div class="panel">
<ul>
<li>
Potato(c. 1864-1928)
</li>
<li>
Onions(c. 1884-1962)
</li>
<li>
Pepper (1886-1921)
</li>
<li>
Gobind Behary Lal (1889-1982)
</li>
</ul>
</div>
</section>
</div>
Let's say if I add a button on the top of the list, how do I code the code the functionality of the button so that it expands all collapsed panels or collapses all expanded panels?
The easiest answer:
Add a button: <button onclick="toggleExpandCollapse();">Expand/Collapse</button>
Add this JS:
function toggleExpandCollapse() {
document.querySelectorAll('.panel').forEach(function(el) {
el.classList.toggle('hidden');
});
}
And lastly, add this css:
.hidden {display:none;}
And you are done!

How to toggle between two menu items on click and close previous when next is toggled?

What am I trying to do. I have a menu navigation with 2 menu items the search and hamburger icon next to each other.
When I click on "MENU" the div will display the menu navigation items and will close when I click once again because of the toggle event.
However, when I open up "MENU" and switch back to "SEARCH" where, a different div should be displayed it messes up the logical structure between these two on toggle.
So, I want to toggle between SEARCH and MENU content no matter which one is selected / toggled. To close previous (remove class and add class to the next active element).
How can I do this?
HTML:
SEARCH
MENU
<nav class="navigation js-navigation">
<div class="content hidden">
<input type="search" placeholder="search" />
</div>
<div class="content hidden">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</nav>
JS:
(() => {
const navigation = document.querySelector('.js-navigation');
if(!navigation) {
return;
}
const hamburger = document.querySelector('.js-hamburger');
const search = document.querySelector('.js-search');
let contents = document.querySelectorAll('.content');
const onClick = (e) => {
e.preventDefault();
contents.forEach((content) => {
content.classList.remove('hidden');
content.classList.add('hidden');
})
}
hamburger.addEventListener('click', onClick);
search.addEventListener('click', onClick);
});
Shouldnt you add:
if (content.classList.contains("hidden")) {
content.classList.remove('hidden');
} else {
content.classList.add('hidden');
}
Changeing classList didnt work for me, but this took effect:
<html>
<body>
SEARCH
MENU
<nav class="navigation js-navigation">
<div id="search" class="content">
<input type="search" placeholder="search" />
</div>
<div id="menu" class="content">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</nav>
<script>
function toggle(id) {
var isHidden = document.getElementById(id).style.visibility == "hidden";
document.getElementById(id).style.visibility = isHidden ? "visible" : "hidden";
}
</script>
</body>
</html>
Also seems you could alternatively go with classList.toggle:
const navigation = document.querySelector('.js-navigation');
const hamburger = document.querySelector('.js-hamburger');
const search = document.querySelector('.js-search');
let contents = document.querySelectorAll('.content');
const onClick = (e) => {
e.preventDefault();
contents.forEach((content) => {
content.classList.toggle('hidden');
})
}
hamburger.addEventListener('click', onClick);
search.addEventListener('click', onClick);

How can I hide nav bar when on top of page

Can anyone help me out with a small responsive web project I'm currently doing?
I want to hide the menu nav bar when the user is on the top most part of the page, and only show it when the user starts scrolling down (on the mobile version), but have no idea how to, below are my code segments (mostly based on W3school template as I'm trying to learn web page making and it is the most reliable source I've found so far):
<!-- Navbar -->
<div class="w3-top">
<ul class="w3-navbar w3-sea-green w3-card-2 w3-left-align">
<li class="w3-hide-medium w3-hide-large w3-opennav w3-right">
<a class="w3-padding-large" href="javascript:void(0)" onclick="myFunction()" title="Toggle Navigation Menu"><i class="fa fa-bars"></i></a>
</li>
<li>HOME</li>
<li class="w3-hide-small">DOWNLOAD</li>
<li class="w3-hide-small">ABOUT</li>
<li class="w3-hide-small">CONTACT</li>
</ul>
</div>
<!-- Navbar on small screens -->
<div id="navDemo" class="w3-hide w3-hide-large w3-hide-medium w3-top" style="margin-top:46px">
<ul class="w3-navbar w3-left-align w3-sea-green">
<li><a class="w3-padding-large w3-hover-text-sea-green-invert" href="#download">DOWNLOAD</a></li>
<li><a class="w3-padding-large w3-hover-text-sea-green-invert" href="#about">ABOUT</a></li>
<li><a class="w3-padding-large w3-hover-text-sea-green-invert" href="#contact">CONTACT</a></li>
</ul>
</div>
<script>
// Used to toggle the menu on small screens when clicking on the menu button
function myFunction() {
var x = document.getElementById("navDemo");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
}
// When the user clicks anywhere outside of the modal, close it
var modal = document.getElementById('ticketModal');
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
<!--Header image-->
<div class="mySlides w3-display-container w3-center">
<img src="pics/header_img.png" style="width:100%; pointer-events:none;" draggable="false">
</div>
Am really appreciating any help, many thanks!
Always use:
.classList.add() // To add the class
.classList.remove() // To remove the class
This makes your code:
function myFunction() {
var x = document.getElementById("navDemo");
if (x.className.indexOf("w3-show") == -1) {
x.classList.add("w3-show");
} else {
x.classList.remove("w3-show");
}
}
And finally, please don't follow W3Schools and you end up like this.
function change(){
navbar=document.getElementsByClassName("w3-top")[0];
if(window.scrollTop>20){
//show
navbar.style.display="block";
}else{
//hide
navbar.style.display="none";
}}
window.onload=window.onscroll=change;
On page load or if the user scroll, check if the user scrolled down...
you have to detect when the user scroll or not and if not scroll add class hidden and if scroll remove class hidden.
$(window).scroll(function (){
var scroll = $(window).scrollTop();
if (scroll >=20) {
$('.w3-top').removeClass('hidden');
}
else {
$('.w3-top').addClass('hidden');
}
});
the css
.hidden {
display: none;
}

Nav with JS (double open)

I have a problem with my JS code, this code active a div with megamenu but i can open 2 megamenu at the same time, i need when i have already clicked the current megamenu disappears for the second is active. You have an idea ?
$(function() {
var menuVisible = false;
$('.contentLink').click(function() {
var office = $(this).attr('data-office');
if (menuVisible) {
$('#_' + office).hide();
$(this).removeClass('on');
menuVisible = false;
return;
}
else
{
$('#_' + office).show();
$(this).addClass('on');
menuVisible = true;
}
});
});
<nav>
<ul class="menu-links">
<li><a data-office="events" class="contentLink">Events</a>
<div class="megamenu center" id="_events">
My mega menu events
</div>
</li>
<li><a data-office="articles" class="contentLink">Articles</a>
<div class="megamenu center" id="_articles">
My mega menu articles
</div>
</li>
</ul>
</nav>
Yes, add this line on your click() function to hide all megamenu before :
$('.megamenu').hide();
I've edit your code to simplify it :
$(function() {
$('.contentLink').click(function() {
$('.megamenu').hide();
menu = $(this).next();
if(menu.is(':visible')){
menu.hide();
}else{
menu.show();
}
});
});
Live example

Remove class with Jquery on a different item

I have a mobile menu button that has an animation, the class changes on click of the menu and click backs to normal when clicked again. A menu also pops out on click.
I want the animation end state to also click back to normal when I click one of the pop out menu anchor links.
Here is my HTML code:
<div class="o-grid__item">
<button id="menu" class="c-hamburger c-hamburger--htx">
<span>toggle menu</span>
</button>
</div>enter code here
<nav class="main-menu">
<ul>
<li>
<a href="#welcome">
<i class="fa"></i>
<span class="nav-text">Home</span>
</a>
</li>
<li>
<a href="#portfolio">
<i class="fa"></i>
<span class="nav-text">Work</span>
</a>
</li>
<li>
<a href="#about">
<i class="fa"></i>
<span class="nav-text">About</span>
</a>
</li>
<li>
<a href="#contact">
<i class="fa"></i>
<span class="nav-text">Contact</span>
</a>
</li>
</ul>
</nav>
Here is the script I'm using to toggle the menu
$(document).ready(function(){
$(".c-hamburger").click(function(){
$(".main-menu").toggleClass("expand-menu");
});
});
Here is the code for the remove/add class for animating the button.
(function() {
"use strict";
var toggles = document.querySelectorAll(".c-hamburger");
for (var i = toggles.length - 1; i >= 0; i--) {
var toggle = toggles[i];
toggleHandler(toggle);
};
function toggleHandler(toggle) {
toggle.addEventListener( "click", function(e) {
e.preventDefault();
(this.classList.contains("is-active") === true) ? this.classList.remove("is-active") : this.classList.add("is-active");
});
}
})();
I need to know how to add remove this class for the menu button, on click of one of my list items in my list? any help much appreciated.
to remove a class from an element instead of just toggling it, use the .removeClass extension for the JQuery element selector. Add this to the anchor links
If you are using jquery anyways, then use this for the class toggling logic
$(".main-menu ul li a").click( function(){
e.preventDefault();
$(this).closest("li").toggleClass("is-active").siblings().removeClass("is-active");
});

Categories