Make sub nav slidedown and slideup toggle - javascript

Here's what I'm trying to do:
Create a navigation with a sub-nav or child page.
When the user clicks on about, I want the about to toggle the Bob li.
It should slide down and slide up when clicked on and off of about.
$(document).ready(function() {
$("#grab").click(function() {
$(".sub-nav").slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
<li id="#grab">About
<ul class="sub-nav">
<li>Bob</li>
</ul>
</li>
<li>Contact</li>
<li>Faqs</li>
</ul>

Your HTML is wrong you have a hashtag before grab id="#grab" it should be id="grab" by default the li contain "Bob" will be show to resolve this issue, add display:none; to the ul either through a class or inline
$(document).ready(function() {
$("#grab").click(function() {
$(".sub-nav").stop().slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
<li id="grab">About
<ul style="display:none" class="sub-nav">
<li >Bob</li>
</ul>
</li>
<li>Contact</li>
<li>Faqs</li>
</ul>

The # is used to reference id, in your tag you're seting the id as #grab, and in your jquery you're setting the .click() event to the class grab.
Then you'll need to change your <li> id to grab:
<li id="grab">
You can add display: none to your <ul>. In that way, when the page load, the sub-nav starts hidden:
You can set this on the tag:
<ul class="sub-nav" style="display: none;">
Or in your css:
.sub-nav{
display: none;
}

Related

Select current element and change values on click

I'm new to Javascript and I've been trying to program a code that changes the value of an attribute and a style when its element is clicked. I have this code and I want that when you click on "<li class="has-sub">" it changes to "<li class="has-sub show">"... and inside it, that "<ul class="sub-menu m-sub" style="display: none;">" changes to "<ul class="sub-menu m-sub" style="display: block;">":
<li class="has-sub">
Hi
<ul class="sub-menu m-sub" style="display: none;">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
When clicked, it should look like this:
<li class="has-sub show">
Hi
<ul class="sub-menu m-sub" style="display: block;">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
I have made the attempt on my own, and tried to place this:
<script type='text/javascript'>
$(document).ready(function change() {
$(this).attr('has-sub','has-sub show');
$(this > ul).css('display','block');
})
</script>
And call the function with "onclick":
<li class="has-sub" onclick"change();">
But I haven't been able to achieve it yet...
Thanks for the help :)
You can use the parent to toggle a class that has display: none applied to it. $(this).children('ul').toggleClass('hide') will target the class hide and then toggle its class on click using toggleClass(). Set the hide class by default on the HTML sub-menu element.
$(document).ready(function(){
$('.has-sub').on('click', function(){
$(this).children('ul').toggleClass('hide')
})
})
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="has-sub show">
Hi
<ul class="sub-menu m-sub hide">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
First of all, you need to add click listener on .has-sub and after that you can add class show.
You need to add class show. It is not an attribute.
Just use .has-sub > ul to get the ul that is direct child of .has-sub.
$(document).ready(function change() {
// $(this).attr("has-sub", "has-sub show");
$(".has-sub").click(function() {
$(this).addClass("show");
$(".has-sub > ul").css("display", "block");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="has-sub">
Hi
<ul class="sub-menu m-sub" style="display: none;">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
You can use this as click handler, then you can remove the onclick"change();"
$(document).ready(function() {
$(".has-sub > a").on("click", function() {
// here you can use
// - $(this).parent() to do something with the li.has-sub
// - $(this).next("ul") to do something with the ul.sub-menu
});
});

How to prevent all parents from toggling when clicking on child link jquery?

So I have something like this:
And some ultra simple jQuery that is toggling the child links when I click the parents ("Spec Sheet", "Instructions" etc) although when I click on one, they all open. Here is the code (is there a simple way to only open one parent per click)?:
$(document).ready(function(){
$("ul#dropdown-download-links li > a").unbind().click(function(e) {
var ulContainer = $(this).closest("ul");
e.preventDefault();
$(ulContainer).slideToggle();
});
});
$(this).closest("ul"); is targeting the wrong element, this targets the first parent ul encountered going up the DOM tree from the clicked a tag
In the below $(this).closest("li").find("ul"); will target the first parent li tag encountered going up the DOM tree from the clicked a tag, then find the ul tag inside that li tag
$(document).ready(function() {
$("ul#dropdown-download-links li > a").unbind().click(function(e) {
var ulContainer = $(this).closest("li").find("ul");
e.preventDefault();
$(ulContainer).slideToggle();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sticky-sidebar">
<ul class="dropdown-menu">
<li>
Where to Buy
</li>
<li>
<ul id="dropdown-download-links" data-sticky="sticky-aside" class="fast-links dropdown">
<div data-domain="http://wacdev.waclighting.com" style="display:none;"></div>
<div data-zspectempid="" style="display:none;">0</div>
<div data-ppid="" style="display:none;">333</div>
<div data-spec-sheet-url="" style="display:none;">/storage/SPECSHEET_PDF/R3CRDT_SPSHT.pdf</div>
<li>SPEC SHEET
<ul id="spec-sheet-option" style="display: none;">
<li><span class="glyphicon glyphicon-align-left" aria-hidden="true"></span>Oculux Architecture</li>
<li>Dim-to-Warm!</li>
</ul>
</li>
<li>INSTRUCTIONS
<ul id="spec-sheet-option" style="display: none;">
<li>Oculux Architecture</li>
<li>Dim-to-Warm!</li>
</ul>
</li>
<li>IES FILES
<ul style="display: none;">
<li>Some value</li>
<li>Some other value</li>
</ul>
</li>
<li>DIMMING REPORT
<ul style="display: none;">
<li>Some value</li>
<li>Some other value</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>

How to add active class using JQuery?

I set the active class by onclick function.
when I click A (parent li) the li tags are active.
But when I click siblings li i.e A11 are active while parent li tags are inactive, the following problems ocur:
all the siblings and parent li tags are hidden
I want to display siblings li tags along with parent li tags
My code:
<div>
<ul id="o_shop_collapse_category">
<li class="active"> A
<ul id="category">
<li>A11</li>
<li>A12</li>
</ul>
</li>
<li>B
<ul id="category">
<li> B12</li>
</ul>
</li>
</ul>
</div>
My javascript:
<script type="text/javascript">
$( document ).ready(function() {
$('#o_shop_collapse_category li:not(.active)').hide();
$('#category li').show();
});
</script>
As you can see in the snippet below, the bunch of code you provided is not enough for us to answer you. The li elements are not even clickable, for us to see the behaviour you describe.
$(document).ready(function () {
$('#o_shop_collapse_category li:not(.active)').hide();
$('#category li').show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="o_shop_collapse_category">
<li class="active"> A
<ul id="category">
<li>A11</li>
<li>A12</li>
</ul>
</li>
<li>B
<ul id="category">
<li> B12</li>
</ul>
</li>
</ul>
</div>

Getting/changing class of an element with other elements in it. JavaScript/JQuery

I made a blog archive in the format of this:
+Year
+Month
Title
Sample code:
<ul>
<span class="toggle">+</span>
<li class="year">$year
<ul>
<span class="toggle">+</span>
<li class="month active">$month
<ul>
<li class="title active">$title</li>
</ul>
</li>
</ul>
</li>
</ul>
I used $(this).next().toggle(), which works fine toggling the lists, but the entire list is expanded in the beginning when the page loads, and I don't want that.
So I changed to changing class names (active/inactive). I want to change the class of the month/title lists to inactive and back when the + span is clicked. The problem is using $(this).next() doesn't work.
If I try $(this).next().hasClass("active");
It will return a false. Or console.log($(this).next().attr("class"));, which gives undefined.
$(this).next().html(); gives:
<li class="month active"><span class="toggle">+</span><ul><li class="title active">...</li></ul></li></ul></li></ul>
The very next thing that follows the + span is the list with class of active, but it doesn't recognize the class? I don't understand why .toggle() works, but this doesn't.
What option do I have to make this work?
The idea is to capture the click event on the span class and toggle active/inactive on the year so that it shows correctly. Here's some psuedo code:
$('.toggle').on('click', function(){
$(this).next().toggleClass('active').toggleClass('inactive');
});
This will only work if the element has a class of inactive on page load, like this:
<ul>
<span class="toggle">+</span>
<li class="year inactive">$year
<ul>
<span class="toggle">+</span>
<li class="month active">$month
<ul>
<li class="title active">$title</li>
</ul>
</li>
</ul>
</li>
</ul>
When you had your initial toggle working but it displayed the items on load, you could have set the next element (the unordered list) to
style="display: none"
As for
console.log($(this).next().attr("class");
You are missing a parenthesis:
console.log( $(this).next().attr("class") );
Hope this helps.
By using little bit of CSS and toggling the class of ul to active only on click will fix your issue. Below is a working example.
$('.toggle').on('click', function() {
$(this).parent().toggleClass('active');
});
ul {
list-style-type: none;
}
ul:not(#MainNode) {
display: none;
}
ul.active > li > ul {
display: block !important;
}
.toggle {
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="MainNode">
<span class="toggle">+</span>
<li class="year">Year
<ul>
<span class="toggle">+</span>
<li class="month active">Month
<ul>
<li class="title active">Title</li>
</ul>
</li>
</ul>
</li>
</ul>

Remove the class of one element and assign it to another using JavaScript

I need to remove the selected class of an <a> and assign it the last <a> instead. Both are nested within individual <li> elements.
Here's an example of the code:
<ul class="tabs clearfix">
<li class="tab">Home</li>
<li class="tab">About</li>
<li class="tab">Profile</li>
<li class="tab">History</li>
<li class="tab">The Beginning of V-Cube</li>
</ul>
How can I achieve this using JavaScript/jQuery? Please advise.
EDIT:
Let's say I don't want to target the last tab specifically. Can the href be used as a selector instead?
EDIT #2:
Thank you so much everyone for the quick response. All your answers were spot on, wish I could mark them all as answers :)
To remove class from an element, use removeClass.
To get the last element, use :last selector or last(). To add new class to element use addClass
$('.selected').removeClass('selected');
$('.tabs li:last a').addClass('selected');
// OR
// $('.tabs li').last().children('a').addClass('selected');
.selected {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="tabs clearfix">
<li class="tab">Home
</li>
<li class="tab">About
</li>
<li class="tab">Profile
</li>
<li class="tab">History
</li>
<li class="tab">The Beginning of V-Cube
</li>
</ul>
Update
Let's say I don't want to target the last tab specifically. Can the href be used as a selector instead?
$('.tabs a[href="#five"]').addClass('selected');
Try this.
$(".tabs li").first().find("a").removeClass("selected");
$(".tabs li").last().find("a").addClass("selected");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="tabs clearfix">
<li class="tab">Home</li>
<li class="tab">About</li>
<li class="tab">Profile</li>
<li class="tab">History</li>
<li class="tab">The Beginning of V-Cube</li>
</ul>
Try this:
$(document).ready(function(){
var classname = $(".tabs li:first-child a").attr("class");
console.log(classname);
$(".tabs li:last-child a").addClass(classname);
$(".tabs li:first-child a").removeClass();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="tabs clearfix">
<li class="tab">Home</li>
<li class="tab">About</li>
<li class="tab">Profile</li>
<li class="tab">History</li>
<li class="tab">The Beginning of V-Cube</li>
</ul>
it is quite easy also in vanilla JS:
document.querySelector('.selected').classList.remove('selected');
document.querySelector('.tabs li:last a').classList.add('selected');
If you want to use an arbitrary a and select the attribute href then you should use this selector:
a[href="HREFVALUE"]
$('.clearfix').find('.selected').removeClass('selected');
$('.clearfix').find('li:last').find('a').addClass('selected');
$("a[href$='five']").addClass('bold');
.selected {
color: red
}
.bold {
font-weight: bold
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="tabs clearfix">
<li class="tab">Home
</li>
<li class="tab">About
</li>
<li class="tab">Profile
</li>
<li class="tab">History
</li>
<li class="tab">The Beginning of V-Cube
</li>
</ul>
Just use .removeClass() and .addClass()
.removeClass()
Remove a single class, multiple classes, or all classes from each element in the set of matched elements.
.addClass()
Description: Adds the specified class(es) to each element in the set of matched elements.

Categories