I have an ul list similar to this:
<ul>
<li class="category">Category 1
<ul>
<li class="product alpha_a">A Product</li>
<li class="product alpha_b">B product</li>
</ul>
</li>
<li class="category">Category 2
<ul>
<li class="product alpha_a">Another Product</li>
<li class="product alpha_c">c product</li>
</ul>
</li>
</ul>
what I am trying to do is hide the li elements that are not of a selected alpha class. I have tried this (simplified here):
$(".alpha_a").addClass("alphaselected");
$(".product li:not(.alphaselected)").hide();
but it doesn't work. I have also tried (among many others):
$("#sitemap li:not(.alphaselected,.category)").hide();
which seems to hide everything.
Any ideas?
Thanks
Try this:
$(".alpha_a").addClass("alphaselected");
$(".product:not(.alphaselected)").hide();
fiddle link
it should be - the product class belongs to the li element so your descendant selector will not return any element
$("li.product:not(.alphaselected)").hide();
Demo: Fiddle
Use:
$(".alpha_a").addClass("alphaselected");
$("li.product:not(.alphaselected)").hide();
Related
I have html code like this:
<ul class="dropdown-menu mega-dropdown-menu">
<li class="should be = col-sm-4">
<ul>
<li class="should be = dropdown-header">Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
<li class="should be = col-sm-4">
<ul>
<li class="should be = dropdown-header">Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
<li class="should be = col-sm-4">
<ul>
<li class="should be = dropdown-header">Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
</ul>
this code is generated from server side, now my question is, how can I append col-sm-4 css class to all li parents and add css class dropdown-header to first li child elements with javascript?
Vanilla Javascript Solution:
By storing all applicable list items in a variable, that can be later ustilised in a for loop, we can iterate through each instance and add the required class.
This solution is preferable if an entire javascript library or framework (like jQuery) is not required for trivial change that only needs to occur once.
Code Snippet Demonstration:
// Get direct descendant list-item children using querySelectorAll and CSS child combinator selector
var listItems = document.querySelectorAll('.dropdown-menu > li');
// Add class to each instance in for loop
for(var i = 0; i < listItems.length; i++) {
listItems[i].className = 'col-sm-4';
}
// Get first list-item child of nested ul element with class name "col-sm-4" using querySelectorAll and CSS :first-child pseudo-selector
var headerListItems = document.querySelectorAll('.dropdown-menu .col-sm-4 li:first-child');
// Add class to each instance in for loop
for(var i = 0; i < listItems.length; i++) {
headerListItems[i].className = 'dropdown-header';
}
// Note: "querySelectorAll" allows for the ability to specify selectors using CSS Selector Syntax
<ul class="dropdown-menu mega-dropdown-menu">
<li >
<ul>
<li>Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
<li >
<ul>
<li >Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
<li >
<ul>
<li >Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
</ul>
jQuery Solution:
Consider using the .addClass() method to add the required classes by specifying the intended selectors as demonstrated in the embedded code snippet below.
This solution is preferable if this change needs to occur more than once or elsewhere in a similar scope.
Code Snippet Demonstration:
jQuery('.dropdown-menu > li').addClass('col-sm-4');
jQuery('.dropdown-menu .col-sm-4 li:first-child').addClass('dropdown-header');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown-menu mega-dropdown-menu">
<li >
<ul>
<li>Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
<li >
<ul>
<li >Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
<li >
<ul>
<li >Item0</li>
<li>Item1</li>
<li>Item2</li>
</ul>
</li>
</ul>
Alternative: Standard CSS Selector Syntax
The elements in question can still be targeted using CSS Selector Syntax with the following methods:
For what would be "col-sm-4": .dropdown-menu > li
Selecting the first direct descendant list-item element using the child combinator (>)
For what would be "dropdown-header": .dropdown-menu ul li:first-child
Selecting the first child list-item element using :first-child pseudo-selector
I have a markup for <ul> as below:
<ul>
<li class="">Insulated And Extruded</li>
<li class="">Grille Type Rolling</li>
<li class="active2">PVC High Speed Doors</li>
<li class="">Swinging doors</li>
</ul>
Here I want to check li has a class named active2, and if it does then I need to remove that class and need to add different class to that li.
This is how I tried it in jQuery:
if($('ul li').hasClass('active2')) {
$(this).removeClass('active2').addClass('active1');
}
But it doesn't work.
Can anybody help me to figure this out?
To use hasClass() you'd need to loop through all the li elements and check them individually.
However there's no need for hasClass() here at all as you can select the .active2 elements directly and call toggleClass() on them, like this:
$('ul li.active2').toggleClass('active2 active1');
.active1 { background-color: yellow; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="">Insulated And Extruded</li>
<li class="">Grille Type Rolling</li>
<li class="active2">PVC High Speed Doors</li>
<li class="">Swinging doors</li>
</ul>
You do not need hasClass(), You can simply do this :
$('ul li.active2').removeClass('active2').addClass('active1');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="">Insulated And Extruded</li>
<li class="">Grille Type Rolling</li>
<li class="active2">PVC High Speed Doors</li>
<li class="">Swinging doors</li>
</ul>
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 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.
I have a drop-down menu that are dynamically added through WordPress. It looks like this:
Pictures
Sea
Forest
City
"Sea", "Forest" and "City" is categories with "Pictures" as parent category.
My question is:
How do I make the "Pictures" category unclickable?
I did this with jQuery:
$(document).ready(function(){
//Make parent links unclickable
$(".page-item-3").click(function(){
return false;
});
});
...and this with CSS:
li.page-item-3 a {
cursor:default;
}
.page-item-3 ul li a {
cursor: pointer;
}
Markup looks like this:
<div id="menu" class="jqueryslidemenu">
<ul>
<li class="cat-item cat-item-1 current_page_item">Blabla</li>
<li class="page_item page-item-2">Blabla
<ul>
<li class="page_item page-item-28">Blabla</li>
<li class="page_item page-item-30">Blabla</li>
<li class="page_item page-item-39">Blabla</li>
</ul>
</li>
<li class="page_item page-item-3">Blabla
<ul>
<li class="page_item page-item-5">Blabla 1</li>
<li class="page_item page-item-7">Blabla 2</li>
<li class="page_item page-item-9">Blabla 3</li>
<li class="page_item page-item-11">Blabla 4</li>
<li class="page_item page-item-13">Blabla 5</li>
</ul>
</li>
<li class="page_item page-item-15">Blabla
<ul>
<li class="page_item page-item-222">Blabla</li>
<li class="page_item page-item-224">Blabla</li>
<li class="page_item page-item-226">Blabla</li>
</ul>
</li>
<li class="page_item page-item-17">Blabla</li>
<li class="page_item page-item-36">Blabla</li>
</ul>
</div>
This almost works But the jQuery code makes all the drop-down links unclickable too.
It would be great if anyone knows how to remove the status bar url while hover the "Pictures" link. But I don't think that is possible to make in moderns browsers such as Safari och Firefox?
Thanks!
I don't know what control you have because of Wordpress but you're having this problem because everything is contained in the title list item (page-item-3) and you're cancelling the click on this item. If you can apply a class to the title link itself, you can apply the jQuery to that directly.
Unfortunately you can't say ".page-item-3 a" because this apply to all links in the list.
Re-Edit - This should select the first link in the list and cancel the click value of that. You may need to apply this for each 'title' link you have.
$(".page-item-3 a:first").click(function() {
return false;
}
$(".page-item-3").children("a").click(function(e) {
e.preventDefault();
});
*****or with CSS*****
.unclickable {
z-index:-1;
}
$(".page-item-3").children("a").addClass("unclickable");
just replace the href attribute value with #. That way when the user clicks on it, the page goes to #, which is the same page they are on, and nothing happens. Keep the CSS you wrote so the hand pointer does not appear when they hover it, but remove the jQuery code.
Using jQuery:
$(".page-item-3>a").attr("href", "#")
Try this:
$(document).ready(function(){
//Make parent links unclickable
$("div > ul > li > a").click(function(){
return false;
});
});
This will disable all the first links in your list without needing the class name.
I use this :
$j = jQuery.noConflict();
$j(document).ready(function(){
//Make parent links unclickable
$j("div[id='nav'] > ul > li > a ").removeAttr("href");
});