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
});
});
Related
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>
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;
}
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>
I want the menu to work like this. When you click Main1 it becomes active and the list will show, when you click it again the list will hide. When Main1 is active and you click Main2, then the Main1 should be inactive and Main2 active.
But my Javascript doesn't seem to make it work well. It makes the Main1 inactive when you click Main2 and the other way, but if you click on any of the active Main it doesn't become incactive. Please help
<div class="directory-section-list">
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main1</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main2</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul >
</div>
Javascript
$(' .list_item .lvl0').click(function(){
$(".list_item.active").removeClass("active");
$(this).parent().toggleClass('active');
});
$(' .list_item .lvl1').click(function(){
$(this).parent().toggleClass('active');
});
Try this,
$('.list_item .lvl0').click(function(){
$('.directory-section-list .active').removeClass('active');
if ($(this).parent().hasClass('active'))
{
$(this).parent().removeClass('active');
}
else
{
$(this).parent().addClass('active');
}
});
$('.list_item .lvl1').click(function(){
$(this).parent().toggleClass('active');
});
Please try this
HTML
<div class="directory-section-list">
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main1</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
</ul>
<ul class="list_item">
<li class="li_lvl lvl1" id="bx_1847241719_2">Main2</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
</ul>
</div>
Java Script
$(' .list_item .lvl0').click(function () {
$(' .list_item .lvl1').parent().removeClass("active");
$(this).parent().toggleClass('active');
});
$(' .list_item .lvl1').click(function () {
$(' .list_item .lvl0').parent().removeClass("active");
$(this).parent().toggleClass('active');
});
Sorry but your HTML List had a couple of errors the
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
will never be closed...
its all about the HTML Structure - i've done another change -> check the HTML Structure of this JS Fiddle: http://jsfiddle.net/marco_rensch/hzu76hgt/32/
I think you want something like this?
$(document).ready(function(){
$('.maindiv').hide();
$( "button" ).click(function() {
$('.maindiv[data-link=' + $(this).data('link') + ']').toggle("fade",300);
});
});
div {
background-color: green;
color: white;
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button class="show" data-link="main1">Main1</button>
<button class="show" data-link="main2">Main2</button>
<div>
<div class="maindiv" data-link="main1">
<h1>This is main1</h1>
</div>
<div class="maindiv" data-link="main2">
<h1>This is main2</h1>
</div>
</div>
Well Thank you all for your help. I managed to do it taking some of your examples and making it work my own way. Thank you again. I will post the Javascript fix.
$(document).ready(function() {
$('.li_lvl').click(function () {
if ($(this).parent().hasClass('active')) {
$(this).parent().removeClass('active');
}
else {
$('.directory-section-list .active').removeClass('active');
$(this).parent().addClass('active');
}
});
This will toggle class active of the parent .li_lvl which is the ul.list_item. If parent has class active it will remove class active. If any other list_item will have class active whilst you click on the other list_item, it will remove class active on the other list_item and make class active on the list_item you clicked.
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.