Toggle active nav-link - javascript

I have a problem with toggling the active nav-link using JavaScript. I think my CSS is causing some problems but I do not know why.
I have the CSS code down at the bottom if that is any help. I have linked Jquery and my own name.js document correctly in my HTML head. I want to toggle the active link when it is visited.
var header = document.getElementById("nav-bar")
var toggled_nav = document.getElementsByClassName("nav-item")
for (var i = 0; i < toggled_nav.length; i++) {
toggled_nav[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
}
#nav-bar {
margin: 27px auto 0;
position: relative;
width: 610px;
height: 50px;
background-color: #34495e;
border-radius: 8px;
font-size: 0;
}
#nav-bar a {
line-height: 50px;
height: 100%;
font-size: 15px;
display: inline-block;
position: relative;
z-index: 1;
text-decoration: none;
text-transform: uppercase;
text-align: center;
color: white;
cursor: pointer;
}
#nav-bar .animation {
position: absolute;
height: 100%;
top: 0;
z-index: 0;
transition: all .5s ease 0s;
border-radius: 8px;
}
a:nth-child(1) {
width: 100px;
}
a:nth-child(2) {
width: 110px;
}
a:nth-child(3) {
width: 180px;
}
a:nth-child(4) {
width: 110px;
}
a:nth-child(5) {
width: 110px;
}
nav .start-home,
a:nth-child(1):hover~.animation {
width: 100px;
left: 0;
background-color: #1abc9c;
}
nav .start-about,
a:nth-child(2):hover~.animation {
width: 110px;
left: 100px;
background-color: #fcf75e;
}
nav .start-blog,
a:nth-child(3):hover~.animation {
width: 180px;
left: 210px;
background-color: #3498db;
}
nav .start-portefolio,
a:nth-child(4):hover~.animation {
width: 90px;
left: 400px;
background-color: #9b59b6;
}
nav .start-contact,
a:nth-child(5):hover~.animation {
width: 110px;
left: 500px;
background-color: #e67e22;
}
<nav id="nav-bar">
<a class="nav-item" href="#">HOME</a>
<a class="nav-item" href="#">POKEMON</a>
<a class="nav-item" href="#">LEAUGE OF LEGENDS</a>
<a class="nav-item" href="#">API-DOC</a>
<a class="nav-item" href="#">ABOUT US</a>
<div class="animation start-home"></div>
</nav>

I simplified your code and created specific active classes for each nav. You can give the parent the click handler and refer to the children through e.target since in this case the children take up the full space of the parent.
var header = document.getElementById("nav-bar")
header.addEventListener("click",function(e){
has_class = header.querySelector(".active");
if(has_class)has_class.classList.remove("active");
e.target.classList.add("active");
});
#nav-bar {
margin: 27px auto 0;
position: relative;
width: 610px;
height: 50px;
background-color: #34495e;
border-radius: 8px;
font-size: 0;
}
#nav-bar a {
line-height: 50px;
height: 100%;
font-size: 15px;
display: inline-block;
position: relative;
z-index: 1;
text-decoration: none;
text-transform: uppercase;
text-align: center;
color: white;
cursor: pointer;
}
#nav-bar .animation {
position: absolute;
height: 100%;
top: 0;
z-index: 0;
transition: all .5s ease 0s;
border-radius: 8px;
}
.active{
border-radius: 8px;
}
a:nth-child(1) {
width: 100px;
}
a:nth-child(2) {
width: 110px;
}
a:nth-child(3) {
width: 180px;
}
a:nth-child(4) {
width: 110px;
}
a:nth-child(5) {
width: 110px;
}
a:nth-child(1).active{
background:#1abc9c;
}
nav .start-home, a:nth-child(1):hover~.animation {
width: 100px;
left: 0;
background-color: #1abc9c;
}
a:nth-child(2).active{
background:#fcf75e;
}
nav .start-about, a:nth-child(2):hover~.animation {
width: 110px;
left: 100px;
background-color: #fcf75e;
}
a:nth-child(3).active{
background:#3498db;
}
nav .start-blog, a:nth-child(3):hover~.animation {
width: 180px;
left: 210px;
background-color: #3498db;
}
a:nth-child(4).active{
background:#9b59b6;
}
nav .start-portefolio, a:nth-child(4):hover~.animation {
width: 90px;
left: 400px;
background-color: #9b59b6;
}
a:nth-child(5).active{
background:#e67e22;
}
nav .start-contact, a:nth-child(5):hover~.animation {
width: 110px;
left: 500px;
background-color: #e67e22;
}
<nav id="nav-bar">
<a class="nav-item" href="#">HOME</a>
<a class="nav-item" href="#">POKEMON</a>
<a class="nav-item" href="#">LEAUGE OF LEGENDS</a>
<a class="nav-item" href="#">API-DOC</a>
<a class="nav-item" href="#">ABOUT US</a>
<div class="animation start-home"></div>
</nav>

For the first two .nav-item I see they are referring to different files. So in their curresponding files, you can mark them active.
For rest of the three .nav-item you can use (I am using JQuery since you mentioned it)
$('#nav-bar').on('click', '.nav-item', function(e) {
$('.nav-item.active', e.currentTarget).removeClass('active');
$(this).addClass('active');
}
make sure the css for the .active is being applied correctly.

You could do something like this; where you remove the active class for each item and then add it to the one that was clicked.
let items = document.querySelectorAll(".nav-item")
items.forEach(item => {
item.addEventListener("click", event => {
const current = document.querySelector('.active')
current.classList.remove('active')
item.classList.add("active")
})
})

Related

FadeInLeft effect when changing content

window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;
if (window.innerWidth > 768) {
document.querySelectorAll('.section1').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});
document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});
body {
background: gray;
padding: 100px;
}
.block-2 {
display: flex;
flex-direction: row;
background: white;
width: 100%;
padding: 50px;
height: auto;
}
.section-left {
position: sticky;
top: 10px;
height: 300px;
/* background: gray; */
width: 100%;
}
.section-right {
background: blue;
width: 100%;
}
.wrap {
margin: 10px;
background: red;
}
.content {
height: 500px;
}
.footer {
width: 100%;
height: 700px;
background: red;
}
.nav {
position: relative;
left: 0;
top: 0;
width: 100%;
background-color: white;
/* padding: 20px;
*/
}
.nav ul {
display: flex;
list-style-type: none;
flex-direction: column;
padding: 0;
}
.nav a {
display: flex !important;
text-decoration: none;
color: black !important;
display: inline-block;
/* margin-right: 25px !important;
*/
}
#media screen and (max-width: 1024px) {}
.subtitle {
opacity: 0;
}
.active {
opacity: 1;
}
.content1 {
position: absolute;
background-color: red;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content2 {
position: absolute;
background-color: gray;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content3 {
position: absolute;
background-color: green;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content4 {
position: absolute;
background-color: blue;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
<body>
<div class="block-2">
<div class="section-left">
<nav class="nav">
<ul>
<li><a href="" class="active subtitle">
<div class="content1">
<h1>O1</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content2">
<h1>O2</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content3">
<h1>O3</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content4">
<h1>O4</h1>
</div>
</a></li>
</ul>
</nav>
</div>
<div class="section-right">
<div class="section1 wrap">
<div class="content">asdf</div>
</div>
<div class="wrap section1 ">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
</div>
</div>
<div class="footer"></div>
</body>
How can I get the FadeInLeft effect when changing content from .opacity=0 to .opacity=1 on the left side.
I tried to solve this problem with the given script, but it did not work for me.
P.S. See this layout in fullscreen.
Here is a very ruff first draft
Since you already have the .active class being added to your .subtitle class to change opacity, you can just tack on CSS Animation to those classes.
In my example I have .subtitle > div set to right: 100%; and .active > div set to right: 0%; with a transition: 300ms;
Which will animate the block from the left side of the screen over to the right side in 300ms. You can play around with this until you get the animation where you'd like.
Here's a great article from MDN with more information about Using CSS Transitions
CSS transitions provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time. For example, if you change the color of an element from white to black, usually the change is instantaneous. With CSS transitions enabled, changes occur at time intervals that follow an acceleration curve, all of which can be customized.
Examples
div {
transition: <property> <duration> <timing-function> <delay>;
}
#delay {
font-size: 14px;
transition-property: font-size;
transition-duration: 4s;
transition-delay: 2s;
}
#delay:hover {
font-size: 36px;
}
.box {
border-style: solid;
border-width: 1px;
display: block;
width: 100px;
height: 100px;
background-color: #0000FF;
transition: width 2s, height 2s, background-color 2s, transform 2s;
}
.box:hover {
background-color: #FFCCCC;
width: 200px;
height: 200px;
transform: rotate(180deg);
}
window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;
if (window.innerWidth > 768) {
document.querySelectorAll('.section1').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});
document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});
body {
background: gray;
padding: 100px;
}
.block-2 {
display: flex;
flex-direction: row;
background: white;
width: 100%;
padding: 50px;
height: auto;
}
.section-left {
position: sticky;
top: 10px;
height: 300px;
/* background: gray; */
width: 100%;
}
.section-right {
background: blue;
width: 100%;
}
.wrap {
margin: 10px;
background: red;
}
.content {
height: 500px;
}
.footer {
width: 100%;
height: 700px;
background: red;
}
.nav {
position: relative;
left: 0;
top: 0;
width: 100%;
background-color: white;
/* padding: 20px;
*/
}
.nav ul {
display: flex;
list-style-type: none;
flex-direction: column;
padding: 0;
}
.nav a {
display: flex !important;
text-decoration: none;
color: black !important;
display: inline-block;
/* margin-right: 25px !important;
*/
}
#media screen and (max-width: 1024px) {}
.subtitle {
opacity: 0;
transition:300ms;
}
.subtitle > div {
transition:300ms;
right:100%;
}
.subtitle > div h1 {
opacity:0;
position:relative;
top:2em;
transition:300ms;
transition-delay:1s;
}
.active {
opacity: 1;
}
.active > div {
right:0;
}
.active > div h1 {
opacity:1;
top: 0;
}
.content1 {
position: absolute;
background-color: red;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content2 {
position: absolute;
background-color: gray;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content3 {
position: absolute;
background-color: green;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content4 {
position: absolute;
background-color: blue;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
<body>
<div class="block-2">
<div class="section-left">
<nav class="nav">
<ul>
<li><a href="" class="active subtitle">
<div class="content1">
<h1>O1</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content2">
<h1>O2</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content3">
<h1>O3</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content4">
<h1>O4</h1>
</div>
</a></li>
</ul>
</nav>
</div>
<div class="section-right">
<div class="section1 wrap">
<div class="content">asdf</div>
</div>
<div class="wrap section1 ">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
</div>
</div>
<div class="footer"></div>
</body>

Javascript event listener overwrites another event listener

so I am trying to create a multilevel navigation for a mobile device and I am running into some issues. I am still learning javascript so please bare with me. Here is a link to the codepen:
https://codepen.io/maciekmat/pen/yLepYKq
So when you press the menu in the top right, a menu will open down. Then I would like to be able to go into sub categories. For example click Test Open, .active class will be assigned, and another menu slides in. Now I would like to have a go back button that essentially removes the .active class.
However what I think is happening, the event listener listens to the whole parent, and anywhere you click inside the subnavigation, it registers it as a click, and runs the .active class. When I click to go back, its like .active is removed and applied back instantly. Any help please?
I tried doing the event.currentEvent !== event.target if statement but had no luck
const nav = document.getElementById('menuIcon')
const dropdown = document.getElementById('menuDropdown')
nav.addEventListener('click', function() {
dropdown.classList.toggle('nav-is-toggled')
});
const grabNavLinks = document.querySelectorAll('.sub-nav-link');
const grabBackLinks = document.querySelectorAll('.nav-link.back');
const subNavLinks = Array.from(grabNavLinks);
const backLinks = Array.from(grabBackLinks);
for (let i = 0; i < subNavLinks.length; i++) {
subNavLinks[i].addEventListener("click", function() {
this.querySelector('.sub-nav').classList.add('active');
});
}
for (let i = 0; i < backLinks.length; i++) {
backLinks[i].addEventListener("click", function() {
document.querySelector('.sub-nav').classList.remove('active');
});
}
#import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght#300;400;600;700&display=swap");
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: "Open sans", sans-serif;
background: #F9F9F9;
box-sizing: border-box;
}
a, p, h1, h2, h3 {
margin: 0;
padding: 0;
text-decoration: none;
}
ul, li {
padding: 0;
margin: 0;
}
header {
background: white;
padding: 24px 30px;
display: flex;
flex-direction: column;
z-index: 10;
position: relative;
}
.top-nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.top-nav .logo {
background: url("images/tcb-logo-brand.svg") no-repeat;
width: 150px;
height: 50px;
background-size: contain;
background-position: center;
}
.top-nav .navigation {
display: flex;
justify-content: space-between;
width: 132px;
height: 26px;
}
.top-nav .navigation .nav-item {
width: 23px;
height: 26px;
margin-left: 10px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.top-nav .navigation .nav-item.menu {
background-image: url("images/menu-icon.svg");
}
.top-nav .navigation .nav-item.notification {
background-image: url("images/bell-icon.svg");
}
.top-nav .navigation .nav-item.my-account {
background-image: url("images/acc-icon.svg");
}
.search {
margin-top: 16px;
}
.search input[type=search] {
outline: none;
border: none;
background: #F6F6F6;
width: 100%;
height: 50px;
font-size: 16px;
padding: 10px 0 10px 20px;
background-image: url("images/search-icon.svg");
background-repeat: no-repeat;
background-position: right 15px top 50%;
}
.search input[type=search]::placeholder {
color: #B7B7B7;
}
span.nav-title {
display: none;
}
nav.main-nav {
width: 100%;
background: #F6F6F6;
transform: translateY(-100%);
z-index: 0;
position: relative;
transition: all 0.3s ease-in-out;
position: absolute;
padding-bottom: 50px;
overflow: hidden;
}
nav.main-nav ul {
padding-top: 2px;
position: relative;
}
nav.main-nav li {
list-style: none;
}
nav.main-nav a {
color: #6D6D6D;
font-size: 16px;
width: 100%;
height: 100%;
display: block;
padding: 18px 30px;
border-bottom: 1px solid #E9E9E9;
}
nav.main-nav li.nav-link.arrow {
background: url("images/right-arrow.svg") no-repeat;
background-position: right 30px top 50%;
}
nav.main-nav ul.sub-nav {
background: #cecece;
width: 100%;
display: flex;
flex-direction: column;
transform: translateX(100%);
overflow: hidden;
visibility: hidden;
opacity: 0;
position: absolute;
top: 0;
left: 0;
transition: transform 0.2s ease;
}
.sub-nav-link > .sub-nav.active {
transform: translateX(0);
visibility: visible;
opacity: 1;
}
nav.nav-is-toggled {
position: static;
opacity: 1;
transform: translateY(0);
transition: all 0.3s ease-in-out;
}
<header>
<div class="top-nav">
<div class="logo"></div>
<div class="navigation">
<div id="menuIcon" class="nav-item menu">test</div>
<div class="nav-item notification"></div>
<div class="nav-item my-account"><span class="nav-title">My Account</span></div>
</div>
</div>
<div class="search">
<input type="search" name="search" id="search" placeholder="Search by store...">
</div>
</header>
<nav id="menuDropdown" class="main-nav">
<ul class="main-nav-ul">
<li class="nav-link">Test</li>
<li class="nav-link arrow sub-nav-link">Test Open
<ul class="sub-nav">
<li class="nav-link back">Go Back</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
</ul>
</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
<li class="nav-link arrow sub-nav-link">Test Open
<ul class="sub-nav">
<li class="nav-link back">Go Back</li>
<li class="nav-link">Test</li>
<li class="nav-link">Test</li>
</ul>
</li>
<li class="nav-link">Test</li>
</ul>
</nav>
<script src="navigation.js"></script>
Go read on event bubbling and how it bubbles through the DOM tree. However due to the way it passes from parent to child (that's it bubbles down the tree) you should call event.stopPropagation(); So that the previous event doesnt bubble into the backLinks event listener.
This is what you should do
for (let i = 0; i < backLinks.length; i++) {
backLinks[i].addEventListener("click", function(event) {
event.stopPropagation();
document.querySelector('.sub-nav').classList.remove('active');
});
}

Uncaught ReferenceError: slide is not defined

I'm trying to make the left arrow in my page change the background color of the container on click, but whenever I click it I get this error: (index):147 Uncaught ReferenceError: slide is not defined I've tried every solution available here and still no luck. Here's the jsfiddle: https://jsfiddle.net/mLr6oax0/
I would do the following:
use element.style.backgroundColor instead of your intended element.setAttribute('style', 'background-color: 'orange')
use of addEventListener with id or class hooks over HTML's onclick
Test the solution below:
var container = document.getElementById("container");
var clickable = document.getElementById('clickable');
clickable.addEventListener('click', function () {
container.style.backgroundColor = 'orange';
});
html, body {
overflow: hidden;
margin: 0;
}
.wrapper {
margin: 0;
overflow: hidden;
}
#container {
background-color: blue;
}
.container {
position: absolute;
overflow: hidden;
margin: 0;
width: 300%;
height: 520px;
display: flex;
background-color: #ccc;
}
.flex-item {
margin-top: 10px;;
margin-right: auto;
width: 500px;
height: 500px;
background-color: #fff;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2);
list-style: none;
}
.flex-item:first-child {
position: absolute;
left: 0px;
margin-left: 15px;
}
.flex-item:nth-child(2) {
position: absolute;
left: 500px;
margin-left: 20px;
}
.flex-item:nth-child(3) {
position: absolute;
left: 1000px;
margin-left: 20px;
}
.flex-item:nth-child(4) {
position: absolute;
left: 1500px;
margin-left: 20px;
}
li {
display: flex;
}
.left-arrow {
position: absolute;
top: 250px;
font-size: 50px !important;
}
.right-arrow {
position: absolute;
top: 250px;
right: 0px;
font-size: 50px !important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<title>Flex</title>
<body>
<div class="wrapper">
<ul class="container" id="container">
<li class="flex-item"></li>
<li class="flex-item"></li>
<li class="flex-item"></li>
<li class="flex-item"></li>
</ul>
<i id='clickable' class="left-arrow fa fa-chevron-left" aria-hidden="true"></i>
<i class="right-arrow fa fa-chevron-right" aria-hidden="true"></i>
</div>
</body>

Ng-repeat doesn't update after pushing value to array, tried $scope.$apply() but returns error

When you open chat and click on a name, it calls $scope.openChat(user) which pushes a name to the $scope.chat.openChats array. The ng-repeat is suppoused to watch this array for new values but does NOT update. I tried using $scope.$apply() after I push the value to array but get this error
Error: [$rootScope:inprog] http://errors.angularjs.org/1.3.14/$rootScope/inprog?p0=%24apply
Thanks for any help! Heres my codepen.
HTML
<div ng-app="MyApp" ng-controller="AppCtrl">
<div id="menubar">
<div class="logo"><img src="http://i.imgur.com/yS9Ug9Z.png"/></div>
<ul class="middle">
<div class="r1">Project Name <i class="glyphicon glyphicon-pencil"></i></div>
<ul class="r2">
<li class="dropdown">
<button href="#" data-toggle="dropdown" class="dropdown-btn">File</button>
<ul class="dropdown-menu">
<li>Action 1</li>
<li>Action 2</li>
<li>Action 3</li>
</ul>
</li>
<li class="dropdown">
<button href="#" data-toggle="dropdown" class="dropdown-btn">Edit</button>
<ul class="dropdown-menu">
<li>Action 1</li>
<li>Action 2</li>
<li>Action 3</li>
</ul>
</li>
<li class="dropdown">
<button href="#" data-toggle="dropdown" class="dropdown-btn">Help</button>
<ul class="dropdown-menu">
<li>Action 1</li>
<li>Action 2</li>
<li>Action 3</li>
</ul>
</li>
</ul>
</ul>
<div class="menu-btns">
<button id="comment-btn"><i class="material-icons">assignment</i> <span>Comment</span></button>
<button id="share-btn"><i class="material-icons">supervisor_account</i> <span>Share</span></button>
<button id="chat-btn" ng-click="openChatDialog()"><i class="material-icons">chat</i> <span>Chat</span></button>
</div>
<button id="user-btn"></button>
<div id="user-drop" class="shadow-1">
<ul>
<li>Smile</li>
<li>You</li>
<li>Goodlookin</li>
<li>Get Shwify</li>
<li>Cellar Door Is Beautiful</li>
<hr/>
<li>Your Profile</li>
<ul class="links">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
</ul>
</div>
</div>
<div id="chat-cntnr">
<div ng-repeat="chat in chat.openChats track by $index" class="chat-box"></div>
</div>
</div>
JS
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
.controller('AppCtrl', function($scope, $mdDialog) {
//CHAT
$scope.chat = {};
$scope.chat.openChats = [];
$scope.collaborators = ['Dan', 'Miles', 'Ryan', 'kevin'];
var chatCntnr = document.getElementById('chat-cntnr');
// open a chat box
var isChatOpen = function(user) {
if ($scope.chat.openChats.indexOf(user) < 0) return false;
else return true;
};
$scope.openChat = function(user) {
if (!isChatOpen(user)) {
if (chatCntnr.style.display !== 'flex') {
chatCntnr.style.display = 'flex';
}
$scope.chat.openChats.push(user);
$scope.$apply();
}
};
// CHAT DIALOG
$scope.openChatDialog = function() {
$mdDialog.show({
controller: 'AppCtrl',
template: '<md-button ng-click="openChat(\'everybody\')">Everybody</md-button><md-button ng-repeat="user in collaborators" ng-click="openChat(user)"><svg class="status-light" height="17" width="17"><circle cx="8" cy="8" r="8" fill="lightGreen" /></svg>{{user}}</md-button>',
hasBackdrop: false,
clickOutsideToClose: true,
openFrom: '#chat-btn',
closeTo: '#chat-btn'
})
};
});
// chat dialog
// chat
/**
* MENUBAR
*/
var dropdownBtns = document.querySelectorAll('.middle .dropdown-btn');
var dropdowns = document.querySelectorAll('.middle .dropdown');
var userBtn = document.getElementById('user-btn');
var userDrop = document.getElementById('user-drop');
document.addEventListener('click', (e) => {
if (userDrop.classList.contains('open')) {
userDrop.classList.toggle('open');
}
});
userBtn.addEventListener('click', (e) => {
userDrop.classList.toggle('open');
e.stopPropagation();
})
for (var i = 0; i < dropdownBtns.length; i++) {
(function() {
var dropdownBtn = dropdownBtns[i];
var k = i;
dropdownBtn.addEventListener('mouseover', () => {
var x = isDropOpen();
if (x > -1 && x !== k) {
dropdowns[x].classList.toggle('open');
dropdowns[k].classList.toggle('open');
}
})
})();
}
var isDropOpen = () => {
for (var i = 0; i < dropdowns.length; i++) {
var dropdownClasses = dropdowns[i].classList;
if (dropdownClasses.contains('open')) return i;
}
return -1;
}
/**
* menubar
*/
CSS
html, body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
html ul, body ul {
padding: 0;
margin: 0;
}
#menubar {
font-family: sans-serif;
background-color: black;
display: flex;
position: relative;
white-space: nowrap;
}
#menubar .logo {
display: flex;
align-items: center;
padding: 10px;
background-color: lightGrey;
}
#menubar .logo img {
height: 40px;
}
#menubar .middle {
padding: 10px;
padding-top: 8px;
padding-bottom: 0px;
color: white;
width: 100%;
position: relative;
font-family: inherit;
margin-left: 8px;
margin-right: 20px;
}
#menubar .middle .r1 {
font-size: 20px;
}
#menubar .middle .r1 i {
position: relative;
top: -1px;
font-size: 12px;
font-weight: 700;
margin-left: 2px;
cursor: pointer;
}
#menubar .middle .r1 i:hover {
color: lightGrey;
}
#menubar .middle .r2 {
margin-top: 2px;
margin-left: -6px;
font-size: 15px;
padding-bottom: 6px;
}
#menubar .middle .r2 li {
display: inline-block;
}
#menubar .middle .dropdown-btn {
position: relative;
outline: 0;
background-color: transparent;
border: none;
cursor: pointer;
padding: 2px 6px;
z-index: 100;
margin: 0 1px;
margin-top: 1px;
}
#menubar .middle .dropdown-btn:hover {
background-color: grey;
}
#menubar .middle .open .dropdown-btn {
background-color: black;
margin: 0 !important;
border: white 1px solid;
border-bottom: none;
}
#menubar .middle .dropdown-menu {
background-color: black;
border: white 1px solid;
border-radius: 0;
margin-top: -1px;
z-index: 10;
}
#menubar .middle .dropdown-menu li {
display: block;
}
#menubar .middle .dropdown-menu a {
color: white;
}
#menubar .middle .dropdown-menu a:hover {
background-color: dodgerBlue;
}
#menubar .menu-btns {
display: flex;
margin: 12px;
margin-right: 0px;
color: white;
right: 0;
}
#menubar .menu-btns button {
outline: 0;
position: relative;
background-color: transparent;
border-radius: 2px;
border: #343436 3px solid;
margin: 0 5px;
padding: 2px 12px;
font-size: 15px;
white-space: nowrap;
}
#menubar .menu-btns button:hover {
background-color: #4d4d50;
}
#menubar .menu-btns button i {
position: relative;
top: 5px;
color: #aeaeae;
}
#menubar .menu-btns button span {
position: relative;
top: -3px;
}
#user-btn {
margin: 10px;
margin-bottom: 8px;
outline: 0;
width: 70px;
background: url("https://www.fillmurray.com/70/92");
border: none;
border-radius: 2px;
}
#chat-btn {
background-color: #343436 !important;
}
#chat-btn:hover {
background-color: #4d4d50 !important;
}
.shadow-1 {
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.2s ease-in-out;
}
#user-drop {
display: none;
position: absolute;
right: 0;
top: 100%;
background-color: white;
}
#user-drop ul {
list-style-type: none;
padding: 6px 0;
padding-bottom: 2px;
font-size: 15px;
font-weight: 500;
}
#user-drop ul li {
cursor: pointer;
padding: 4px 16px;
padding-right: 38px;
}
#user-drop ul li:hover {
background-color: #e7e7e7;
}
#user-drop ul hr {
margin: 8px 0;
border-top: black 1px solid;
}
#user-drop ul .links {
padding-top: 0;
}
#user-drop ul .links li {
display: inline-block;
padding-right: 2px;
font-size: 11px;
color: darkGrey;
}
#user-drop ul .links li:hover {
background-color: white;
color: black;
}
#user-drop.open {
display: initial;
}
md-dialog {
position: absolute;
right: 25px;
top: 80px;
}
md-dialog svg {
position: absolute;
left: 16px;
top: 11px;
}
#chat-cntnr {
display: none;
position: fixed;
bottom: 0;
right: 0;
}
#chat-cntnr .chat-box {
height: 250px;
width: 200px;
background-color: blue;
border: 1px solid black;
margin: 0 4px;
}
#chat-cntnr .chat-box:last-child {
margin-right: 0;
}
The problem is that $mdDialog is creating another (isolated) scope. To use your existing scope you have to call it like this:
$mdDialog.show({
scope: $scope,
controller: 'AppCtrl',
...
For further information check this post.
Also, you have to remove $scope.$apply(): you have to call it only when changes happen outside Angular (in a setTimeout() for example).
Why do I need to link the scope?
Short answer: because $mdDialog documentation says so
The dialog is always given an isolate scope.
Long answer: $mdDialog is a service that basically adds a directive to the page
The dialog's template must have an outer < md-dialog > element
Since directives can be added multiple times in a page, by default they have an isolated scope (see Angular documentation on directive), but you can link your scope to a directive if you need it.

How Do I Toggle Tabs in JQuery

I am trying to create a tabbed content area which opens and closes each section. My HTML is as follows:
<div class="more-info">
<p>HELLO</p>
</div>
<div class="more-info">
<p>GOODBYE</p>
</div>
The JQuery is
$("a.toggle").click(function () {
$(this).find(".more-info").slideToggle("slow");
});
and my styles are :
a.open {display:block; width:30px; height:30px; background:#999;}
.more-info {display:none; width:100%;}
The idea is to click on the a link and open the it's content box. How do I do this? Doesn't seem to work? The only thing is I can't use unique IDs as the way the page will be created. Therefore, this has to work on a generic class.
You need to slide the required section down and any currently open section up.
Try :
$("a.toggle").on('click', function (e) {
e.preventDefault();
var $section = $(this).next(".more-info").slideDown("slow");
$(".more-info").not($section).slideUp("fast");
});
Try this :
$("a.toggle").on('click', function (e) {
e.preventDefault();
var $a = $(this).next(".more-info");
if($a.is(':visible')){
$a.hide();
}else{
$a.show();
}
});
Check this well designed toggle effect
$('#ce-toggle').click(function(event) {
$('.plan-toggle-wrap').toggleClass('active');
});
$('#ce-toggle').change(function(){
if ($(this).is(':checked')) {
$('.tab-content #yearly').hide();
$('.tab-content #monthly').show();
}
else{
$('.tab-content #yearly').show();
$('.tab-content #monthly').hide();
}
});
body{
margin:0;
}
.plan-toggle-wrap {
text-align: center;
padding: 10px;
background-color: rgb(75,88,152);
position:sticky;
top:0;
}
.toggle-inner input {
position: absolute;
left: 0;
width: 100%;
height: 100%;
margin: 0;
border-radius: 25px;
right: 0;
z-index: 1;
opacity: 0;
cursor: pointer;
}
.custom-toggle {
position: absolute;
height: 25px;
width: 25px;
background-color: #ffffff;
top: 4px;
left: 5px;
border-radius: 50%;
transition: 300ms all;
}
.toggle-inner .t-month, .toggle-inner .t-year {
position: absolute;
left: -70px;
top: 5px;
color: #ffffff;
transition: 300ms all;
}
.toggle-inner .t-year {
left: unset;
right: -85px;
opacity: 0.5;
}
.active > .toggle-inner .t-month {
opacity: 0.5;
}
.active > .toggle-inner .t-year {
opacity: 1;
}
.toggle-inner input:checked + span {
left: 43px;
}
.toggle-inner {
width: 75px;
margin: 0 auto;
height: 35px;
border: 1px solid #ffffff;
border-radius: 25px;
position: relative;
}
.tab-content > div {
display: flex;
justify-content: center;
align-items: center;
background-color: rgb(94,110,191);
color: #fff;
height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="plan-toggle-wrap">
<div class="toggle-inner">
<input id="ce-toggle" type="checkbox">
<span class="custom-toggle"></span>
<span class="t-month">Yearly</span>
<span class="t-year">Monthly</span>
</div>
</div>
<div class="tab-content">
<div id="monthly">MONTHLY</div>
<div id="yearly">YEARLY</div>
</div>
https://codepen.io/Vikaspatel/pen/yRQrpZ

Categories