Collapse slideToggle on Click jQuery - javascript

I'm currently trying to make a sidebar menu that requires a lot of javascript; making a menu item active in class when clicked, and making it unactive when another item is clicked. The problem I'm having is that some Menu items have submenu items. Now when I click them, using jQuery, they slidetoggle to open, but when I click on another item, they too slideToggle to open. I am trying to make it so that when I click a different item, slidetoggle is undone on the other items
I'm sorry if my english is poor but I hope all understand what I am saying
Here's a jsFiddle
<script>
$(document).ready(function(){
var guts = $('#guts').css('display');
var guts2 = $('#guts2').css('display');
var guts3 = $('#guts3').css('display');
$("#click").click(function(){
$("#guts").slideToggle("fast");
if (guts2 == 'block')
$("#guts2").slideToggle("fast");
if (guts3 == 'block')
$("#guts3").slideToggle("fast");
$(this).addClass("active").siblings('.active').removeClass('active');
});
$("#click2").click(function(){
$("#guts2").slideToggle("fast");
if (guts == 'block')
$("#guts").slideToggle("fast");
if (guts3 == 'block')
$("#guts3").slideToggle("fast");
$(this).addClass("active").siblings('.active').removeClass('active');
});
$("#click3").click(function(){
$("#guts3").slideToggle("fast");
if (guts2 == 'block')
$("#guts2").slideToggle("fast");
if (guts == 'block')
$("#guts").slideToggle("fast");
$(this).addClass("active").siblings('.active').removeClass('active');
});
$("#home").click(function(){
$(this).addClass("active").siblings('.active').removeClass('active');
if (guts == 'block')
$("#guts").slideToggle("fast");
if (guts2 == 'block')
$("#guts2").slideToggle("fast");
if (guts3 == 'block')
$("#guts3").slideToggle("fast");
});
});
</script>
<div id="links">
Home
Staff
<div id="guts">
• Staff List
</div>
Locations
<div id="guts2">
• Location List
</div>
Calendar
</div>

Your variables are out of scope for what you want to happen. You are declaring them globally and when each of your click functions are called it doesn't update the variable, it grabs what the variable was initially was on page load which is 'none'.
Place the variables inside the functions so that it updates those variables when they are called.
Instead of:
var guts = $('#guts').css('display');
var guts2 = $('#guts2').css('display');
var guts3 = $('#guts3').css('display');
$("#click").click(function(){
$("#guts").slideToggle("fast");
if (guts2 == 'block')
$("#guts2").slideToggle("fast");
if (guts3 == 'block')
$("#guts3").slideToggle("fast");
$(this).addClass("active").siblings('.active').removeClass('active');
});
Do:
$("#click").click(function(){
var guts = $('#guts').css('display');
var guts2 = $('#guts2').css('display');
var guts3 = $('#guts3').css('display');
$("#guts").slideToggle("fast");
if (guts2 == 'block') {
$("#guts2").slideToggle("fast");
}
if (guts3 == 'block') {
$("#guts3").slideToggle("fast");
}
$(this).addClass("active").siblings('.active').removeClass('active');
});
Optionally:
var guts, guts2, guts3;
$("#click").click(function(){
guts = $('#guts').css('display');
guts2 = $('#guts2').css('display');
guts3 = $('#guts3').css('display');
$("#guts").slideToggle("fast");
if (guts2 == 'block') {
$("#guts2").slideToggle("fast");
}
if (guts3 == 'block') {
$("#guts3").slideToggle("fast");
}
$(this).addClass("active").siblings('.active').removeClass('active');
});
DEMO

I've rewritten the code using unordered list menu (my favourite for menus). Instead of adding click event to each menu item i've added one event that handles everything ( if you have custom stuff to add to any item, you can just include it using a conditional statement )
HTML:
<ul id="links">
<li>Home</li>
<li>Locations
<ul class="submenu">
<li>Location List</li>
</ul>
</li>
<li>Staff
<ul class="submenu">
<li>Staff List</li>
</ul>
</li>
<li>Calendar</li>
</ul>
Javascript
$(document).ready(function () {
$('#links a').click(function () {
if (!$(this).hasClass('.active')) {
$('.active').removeClass('active');
$(this).addClass('active');
}
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
$(this).next().slideToggle(250);
} else if ($(this).next('ul').length > 0) {
$('.toggled').next().slideToggle(250);
$('.toggled').removeClass('toggled');
$(this).addClass('toggled');
$(this).next().slideToggle(250);
} else if(!$(this).parent().parent().hasClass('submenu')) {
$('.toggled').next().slideToggle(250);
$('.toggled').removeClass('toggled');
}
return false;
})
});
And finally some CSS:
#links,
#links ul{
display: block;
padding: 0;
margin: 0;
list-style: none;
text-align: center;
}
#links a {
display: block;
padding: 1px 0
}
#links a.active {
background-color: rgb(0, 173, 255);
}
#links ul{
display: none
}
Check the DEMO

Related

JavaScript - click responding after one extra click

I am trying to create a drop-down list using CSS and JavaScript.
document.querySelector('.dropdown-btn').addEventListener("click", function() {
let list = document.getElementById("project-list");
if (list.style.display === "none") {
list.style.display = "inline-block";
} else {
list.style.display = "none";
}
});
#project-list {
list-style-type: none;
display: none;
position: relative;
}
<ul>
<li class="projects">Projects
<button class="dropdown-btn">Show<i class="fas fa-angle-double-down"></i></button>
<br>
<ul id="project-list">
<li>Hello</li>
<li>World</li>
</ul>
</li>
</ul>
You can try it here. It responds after one extra click, but I am unable to figure out the reason. I am learning the front-end. How can I fix it?
The problem is that list.style.display is an empty string the first time you click the button. You need to check for that, as well:
document.querySelector('.dropdown-btn').addEventListener("click", function() {
let list = document.getElementById("project-list");
if (!list.style.display || list.style.display === "none") {
list.style.display = "inline-block";
} else {
list.style.display = "none";
}
});
#project-list {
list-style-type: none;
display: none;
position: relative;
}
<ul>
<li class="projects">Projects
<button class="dropdown-btn">Show<i class="fas fa-angle-double-down"></i></button>
<br>
<ul id="project-list">
<li>Hello</li>
<li>World</li>
</ul>
</li>
</ul>
It appears to respond after the second click, because the list.style.display is an empty string when you first click it.
Surprised? The CSS rule applies to the element, but it doesn't apply to the JavaScript object.
To get the actual style of the element (including CSS rules and inline styles), you can use getComputedStyle().
For example:
document.querySelector('.dropdown-btn').addEventListener("click", function() {
let list = document.getElementById("project-list");
let style = getComputedStyle(list)
if (style.display === "none") {
list.style.display = "inline-block";
} else {
list.style.display = "none";
}
});

Pagination : Remove element using jquery?

I have a section where i have to paginate records.
Now the issue is the number gets added but i want to remove the prev number
I have currently having something as below:
Prev 1 2 3 Next
When i click on next 4 gets added and it becomes
Prev 1 2 3 4 Next
When i click on next again 5 gets added and it becomes
Prev 1 2 3 4 5 Next
What i am trying to do and what should be having
Prev 1 2 3 Next
When i click on next 4 gets added and it should become
Prev 2 3 4 Next
When i click on next again 5 gets added and it becomes
Prev 3 4 5 Next
When i click on Previous Now it should be
Prev 2 3 4 Next
Please find my runnable code below:
$('ul.pagination').on('click', 'a', function() { // listen for click on pagination link
if($(this).hasClass('active')) return false;
var active_elm = $('ul.pagination a.active');
if(this.id == 'next'){
var _next = active_elm.parent().next().children('a');
if($(_next).attr('id') == 'next') {
// appending next button if reach end
var num = parseInt($('a.active').text())+1;
active_elm.removeClass('active');
$('<li><a class="active" href="#">'+num+'</a></li>').insertBefore($('#next').parent());
return;
}
_next.addClass('active');
}
else if(this.id == 'prev') {
var _prev = active_elm.parent().prev().children('a');
if($(_prev).attr('id') == 'prev') return false;
_prev.addClass('active');
} else {
$(this).addClass('active');
}
active_elm.removeClass('active');
});
ul.pagination {
display: inline-block;
padding: 0;
margin: 0;
}
ul.pagination li {display: inline;}
ul.pagination li a {
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
transition: background-color .3s;
border: 1px solid #ddd;
}
ul.pagination li a.active {
background-color: #4CAF50;
color: white;
border: 1px solid #4CAF50;
}
ul.pagination li a:hover:not(.active) {background-color: #ddd;}
div.center {text-align: center;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<ul class="pagination">
<li><a id="prev">«</a></li>
<li><a id="test1" href="#">1</a></li>
<li><a id="test2" class="active" href="#">2</a></li>
<li>3</li>
<li>»</li>
</ul>
</div>
Use this after adding next number
$('#prev').parent().next().remove();
Codepen http://codepen.io/mastersmind/pen/ZBJZjo
Here is how I would do it.
I would add a class to the 3 <li> tags with the numbers inside for easy access with the jQuery selector.
Inside the if-statement where you check weather the next button has the id next, remove the first child like so:
$('.three_links').first().remove();
and add the next number after the last child like so:
$('.three_links').last().after('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
and if the id is prev remove the last child and add the previous number before the first child but only if the previous number is greater than 1:
if(num > 0){
active_elm.removeClass('active');
$('.three_links').last().remove();
$('.three_links').first().before('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
}
Here is a working jsfiddle.
html:
<div class="center">
<ul class="pagination">
<li>«</li>
<li class="three_links"><a id="test1" href="#">1</a></li>
<li class="three_links"><a id="test2" class="active" href="#">2</a></li>
<li class="three_links"><a id="test3" href="#">3</a></li>
<li>»</li>
</ul>
</div>
js:
$('ul.pagination').on('click', 'a', function() { // listen for click on pagination link
if($(this).hasClass('active')) return false;
var active_elm = $('ul.pagination a.active');
if(this.id == 'next'){
var _next = active_elm.parent().next().children('a');
if($(_next).attr('id') == 'next') {
// appending next button if reach end
var num = parseInt($('a.active').text())+1;
active_elm.removeClass('active');
$('.three_links').first().remove();
$('.three_links').last().after('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
return;
}
_next.addClass('active');
}
else if(this.id == 'prev') {
var _prev = active_elm.parent().prev().children('a');
if($(_prev).attr('id') == 'prev'){
var num = parseInt($('a.active').text())-1;
if(num > 0){
active_elm.removeClass('active');
$('.three_links').last().remove();
$('.three_links').first().before('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
}
return;
}
_prev.addClass('active');
} else {
$(this).addClass('active');
}
active_elm.removeClass('active');
});
Use below script:
$('ul.pagination').on('click', 'a', function() { // listen for click on pagination link
if($(this).hasClass('active')) return false;
var active_elm = $('ul.pagination a.active');
if(this.id == 'next'){
var _next = active_elm.parent().next().children('a');
if($(_next).attr('id') == 'next') {
// appending next button if reach end
var num = parseInt($('a.active').text())+1;
active_elm.removeClass('active');
$('<li><a class="active" href="#">'+num+'</a></li>').insertBefore($('#next').parent());
var hidenum = parseInt($('a.active').text())-2;
if(hidenum > 0){
$('#next').parent().prev().prev().prev().prev().hide();
}
return;
}
_next.addClass('active');
}
else if(this.id == 'prev') {
var _prev = active_elm.parent().prev().children('a');
if($(_prev).attr('id') == 'prev') return false;
_prev.addClass('active');
} else {
$(this).addClass('active');
}
active_elm.removeClass('active');
});

How to open a box on screen by clicking a link and hide it when clicked outside in JS

My goal is to have #box2 appear when I click on #box1 but when you click on something other than #box2, it will display none and only #box1 will show.
Here are my 2 boxes, they are just 2 styled divs:
var condition;
$(document).click(function() {
if (condition === 'block') {
$(":not(#box2)").click(function() {
$("#box2").hide();
});
}
})
$('#box1').click(function(e) {
$('#box2').css('display', 'block');
condition = 'block';
});
$('#box2').click(function(e) {
$('#box2').css('display', 'none');
condition = 'none';
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" style="width: 300px; height: 300px; background-color: red; margin-left: 100px; margin-bottom: 50px; position: absolute;">
</div>
<div id="box2" style="width: 300px; height: 300px; background-color: blue; margin-left: 150px; display: none; position: absolute;">
</div>
This current code works correctly the first time but after that, it wont run again. I am just wondering if there is a reset function or where I am going wrong?
Really what I want to do is make this work on an ipad so when the user clicks/taps away from the box, it will close. If there are better ways to do this on the Ipad tablet, please let me know!!
Any ideas?
Don't overcomplicate things. This is all the javascript you need, get rid of everything else:
$(document).click(function () {
$('#box2').hide();
});
$('#box1').click(function (e) {
e.stopPropagation();
$('#box2').show();
});
You could just filter event target at document level:
$(document).on('click', function(e) {
$('#box2').toggle(!!$(e.target).closest('#box1').length);
});
-jsFiddle-
You can listen to all click events of the document and then use the event.target to detect which element is being clicked. if the clicked element is box1 and box2 is not being shown then display it to the user. in any other condition we can hide the box2 if it's not the element being clicked. here is the vanilla JavaScript code to achieve this:
<html>
<body>
<div id='box1'>BOX ONE</div>
<div id='box2' style="display: none;">BOX TWO</div>
<script>
document.addEventListener('click', function(event) {
var secondBox = document.getElementById('box2')
if(event.target.id === 'box1' && secondBox.style.display === 'none'){
secondBox.style.display = 'block'
} else if (event.target.id !== 'box2') {
secondBox.style.display = 'none'
}
})
</script>
</body>
</html>
And if you are into DRY (Do not repeat yourself), you can define a function for this task. Take look at this modified version of the script:
function addOpenHandler(handler, target){
document.addEventListener('click', function(event) {
if(event.target === handler && target.style.display === 'none'){
target.style.display = 'block'
} else if (event.target !== target) {
target.style.display = 'none'
}
})
}
addOpenHandler( document.getElementById('box1'), document.getElementById('box2') )
$(document).click(function () {
if (condition === 'block')
{
$(":not(#box2)").click(function () {
$("#box2").hide();
});
}
})
The line $("#box2").hide(); is firing after every click

Making JavaScript menu close when clicking outside

I'm basically trying to make open menu close when user click anywhere. im new and i dont know what is problem. so far i am using this code, here is my html, css and javaScript. i think problem is in my JavaScript.
thanks for help.
HTML
<div class="menu-button" style="width:23px; cursor: pointer;" onClick="show_menu()"><span style="color:#b0acac;">▼</span></div>
<div id="dropdown_menu" class="hidden_menu">
<ul id="container">
<li>Settings<br></li>
<li>Log Out</li>
</ul>
</div>
CSS
.menu-button{
position: relative;
left:1556px;
top:-43px;
}
.hidden_menu{
display:none
}
#dropdown_menu ul li {
text-decoration:none;
display: inline;
cursor: pointer;
position: relative;
left:-20px;
top:2px;
}
#dropdown_menu ul{
width:80px;
height:90px;
background-color:#efefef;
position:relative;
top:-64px;
left:1460px;
border-color:#ff0000;
border-width:2px;
}
JavaScript
<script>
function show_menu(){
var menu = document.getElementById('dropdown_menu');
if(menu.style.display == 'block'){
menu.style.display = 'none';
}else {
menu.style.display = 'block';
}
}
function hide_menu(){
var menu = document.getElementById('dropdown_menu');
if(menu.style.display == 'none'){
menu.style.display = 'block';
}
}
var cl = document.getElementById("body");
cl.addEventListener("click", hide_menu);
</script>
This can help you.
HTML Code
<div class="menu-button" style="width:23px; cursor: pointer;" ><span id="button" style="color:#b0acac;">Show Menu</span></div>
<div id="dropdown_menu" class="hidden_menu">
<ul id="container">
<li>Settings<br></li>
<li>Log Out</li>
</ul>
</div>
Css
.hidden_menu { display:none;}
JavaScript Code
var dropMenu = document.getElementById('dropdown_menu'),
menuButton = document.getElementById('button'),
dropUL = document.getElementById('container').childNodes;
function hide_menu(evt){
evt = evt || window.event; // get window.event if evt is falsy (IE)
var targetElement = evt.target || evt.srcElement; // get srcElement if target is falsy (IE)
if(targetElement === menuButton || targetElement.nodeName.toLowerCase() === 'li' ){
dropMenu.style.display = 'block'
} else {
dropMenu.style.display = 'none'
}
}
// For legacy broser(IE8 and IE7) support
function addEvent(el, type, fn){
if(typeof addEventListener !== 'undefined'){
el.addEventListener(type, fn, false)
} else {
el.attachEvent('on'+type, fn);
}
}
addEvent(document, 'click', hide_menu);
Demo
If you want plain js:
document.addEventListener('click', function(e){
console.log(e.target.id)
if(e.target.id!=="dropdown_menu")
console.log("document Clicked");
});
It is same as above function but written in javascript
Try
function hide_menu(e){
var menu = document.getElementById('dropdown_menu');
if(e.target != menu) {
menu.style.display = 'none';
}
}
document.body.addEventListener("click", hide_menu);
$('body').click(function(){
if($(this).attr('id')!='dropdown_menu' && !$(this).hasClass('menu-button'))
// code to close the menu
});
Making sure that the click is not on the div for menu

Clear all the open div's

I have a script that open's div's by doing an onclick="toogle_visibility(id)
event but how do i do when i want to close the div that is open and open
the new div ?
Javascript/jQuery:
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
HTML:
<div class="navBar">
Social
Följer
Bokmärken
</div>
<div id="Social">
#Liam_Rab3 - TWITTER<br>
#Liam_Rab3 - INSTAGRAM<br>
#LiamRab3- FACEBOOK<br>
#Liam_Rab3 - YOUTUBE<br>
#Liam_Rab3 - FLICKR<br>
#Liam_Rab3 - TUMBLR<br>
</div>
<div id="Foljer">
Sebbe Stakset (Kartellen)
</div>
CSS:
a:link {
color:white;
text-decoration:none;
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
transition:.5s;
}
a:hover {
color:white;
text-decoration:none;
font-size:100%;
}
a:visited {
text-shadow:0px 0px 0px #0066BB;
color:white;
}
#social {
display:none;
}
#Foljer {
display:none;
}
DISCLAIMER!
These links in the #social and #bokmarken links is'nt for commercial purpose.
You can use JQuery Toggle
<div id="clickme">
Click here !!!
</div>
<a href="#social" >Social</a>
$( "#clickme" ).click(function() {
$( "#social" ).toggle(); //With no parameters, the .toggle() method simply toggles the visibility of elements:
});
First choose the control you are willing to hide/show, then use that control's id as follows:
$('#<id-of-that-control>').toggle();
Now you can call that in the onclick event handler of a button or div as you wish.
How it might appear for you is:
JS
function toggle_visibility(id) {
$('#' + id).toggle();
}
HTML
<div class="navBar">
Social
Följer
Bokmärken
</div>
Update:
As pointed out by Brodie, seemingly you might always look into the solution provided by Niet the Dark Absol. As he provides you a pure JS implementation. My solution will give you insight of using a library like JQuery and it's API of toggle. Jquery provides a wide range of built-in functionality that helps you to do things quickly. What my piece of code provides you is usage of an api i.e. toggle, which when used will be same as the hide and show behavior.
Basically, you need to close all DIVs, and toggle the current one.
Try this:
var ids = ['Social','Foljer','Bokmarken'];
function toggle_visibility(id) {
var l = ids.length, i, e;
for( i=0; i<l; i++) {
e = document.getElementById(ids[i]);
if( id != ids[i])
e.style.display = 'none';
else if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
}

Categories

Resources