Making parent link unclickable in a drop-down menu with jQuery - javascript

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");
});

Related

How to toggle <li> in a nested list?

I'm trying to be able to toggle these sub menus one at a time, I'm getting lost in nests and cant quite figure out how to target the correct list item,
I found that I should be using find() instead of children() as it can go deeper in the nest but still no luck in getting it working.
<ul>
<li>Profile</li>
<li>Edit</li>
<li class="drop-nav"> See your products
<ul>
<li class="drop-nav"> Mens
<ul>
<li> jumpers </li>
<li> t shirts </li>
</ul>
</li>
<li class="drop-nav"> Womens
<ul>
<li> hoodies </li>
<li> leggings </li>
</ul>
</li>
</ul>
</li>
</ul>
$(".drop-nav").on("click", function(e){
e.preventDefault();
});
li ul{
display: none;
}
You could use $(this).find('ul').eq(0) to get the ul, but I would delegate the changing of the display to the stylesheet, but use javascript to add a class where applicable. This will give you many more options for the design of your dropdown later.
$(".drop-nav").on("click", function(e) {
e.preventDefault()
// don't allow the event to fire horizontally or vertically up the tree
e.stopImmediatePropagation()
// switch the active class that you can use to display the child
$(this).toggleClass('active')
})
/* don't target ll list items in you page, be more specific */
.drop-nav > ul {
display: none;
}
.drop-nav.active > ul {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Profile</li>
<li>Edit</li>
<li class="drop-nav"> See your products
<ul>
<li class="drop-nav"> Mens
<ul>
<li> jumpers </li>
<li> t shirts </li>
</ul>
</li>
<li class="drop-nav"> Womens
<ul>
<li> hoodies </li>
<li> leggings </li>
</ul>
</li>
</ul>
</li>
</ul>
I would add more descriptive class names in your markup, and make them easier to target with CSS and jQuery.
To toggle the menus you could do something like the following:
$(".dropdown-trigger1").on("click", function() {
// Toggle the first menu
$(".dropdown-one").toggleClass("open");
// Close the submenus
$(".dropdown-two").removeClass("open");
});
$(".dropdown-trigger2").on("click", function(e) {
// Prevent a click on a submenu from closing the menu
e.stopPropagation();
// Close any open submenu
$(".dropdown-two").removeClass("open");
// Open the submenu that has been clicked
$(this).find(".dropdown-two").toggleClass("open");
});
li ul {
display: none;
}
.dropdown-one.open {
display: block;
}
.dropdown-two.open {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Profile</li>
<li>Edit</li>
<li class="dropdown-trigger1"> See your products
<ul class="dropdown-one">
<li class="dropdown-trigger2"> Mens
<ul class="dropdown-two">
<li> jumpers </li>
<li> t shirts </li>
</ul>
</li>
<li class="dropdown-trigger2"> Womens
<ul class="dropdown-two">
<li> hoodies </li>
<li> leggings </li>
</ul>
</li>
</ul>
</li>
</ul>
You haven't described about how you activate each sub-menu, so I will describe solution little bit abstractly. Solution is based on your HTML structure an will work if you wouldn't change it.
$('.drop-nav a').on('click', function() {
// This next method returns next element in DOM that is after clicked a link.
// Based on your HTML it would be ul that holds your sub-menu.
var subMenu = $(this).next();
// Here using subMenu selector to make something with sub-menu...
// Example: adding CSS inline to sub. In your situation it may be something else...
$(subMenu).css({ 'display' : 'block' });
});

Remove class if exist and add new one using jquery

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>

How to iterate through each parent list items in jquery?

I just started working with jQuery and I'm running into a bit of a snag with iterating through each parent UL's list items.
I have a simple accordion menu where I'm adding transition-delay inline style to each individual list item. The issue I have is that I'm not sure how to iterate through each set of parent's list items.
Below is an example of what is occurring on every list item.
<ul class="sub-menu">
<li style="transition-delay: 0ms;></li>
<li style="transition-delay: 25ms;>
<ul class="sub-menu">
<li style="transition-delay: 50ms;>
<li style="transition-delay: 75ms;>
<li style="transition-delay: 100ms;>
</ul>
</li>
<li style="transition-delay: 125ms;></li>
<li style="transition-delay: 150ms;></li>
<li style="transition-delay: 175ms;></li>
</ul>
This is what I'm looking to achieve:
<ul class="sub-menu">
<li style="transition-delay: 0ms;></li>
<li style="transition-delay: 25ms;>
<ul class="sub-menu">
<li style="transition-delay: 0ms;>
<li style="transition-delay: 25ms;>
<li style="transition-delay: 50ms;>
</ul>
</li>
<li style="transition-delay: 50ms;></li>
<li style="transition-delay: 75ms;></li>
<li style="transition-delay: 100ms;></li>
</ul>
This is what my jQuery looks like:
$('ul.mobile-menu li.menu-item-has-children ul.sub-menu li').each(function(i){
$(this).css({ 'transition-delay': (i*25)+"ms" });
});
Any help would greatly be appreciated as I am just getting started with jQuery. I created a codepen so you can see the menu in action and visually see the issue.
http://codepen.io/creativenauts/pen/wGLqPg
Here is my approach:
$('.sub-menu').each(function() {
// $(this) = single ul element
$(this).children('li').each(function(idx, el){
// idx = index of current list [0 ... number]
// $(el) = single li element
$(el).css('transition-delay', (idx * 25) + 'ms');
});
});
But in this use case (w.r.t. the size of the list) you can and should use CSS, something like this.
You could use .index(), which gives an element's position among its siblings:
$('ul.mobile-menu li.menu-item-has-children ul.sub-menu li').each(function(){
$(this).css({ 'transition-delay': ($(this).index()*25)+"ms" });
});
Like this:
$('ul.mobile-menu li.menu-item-has-children ul.sub-menu').each(function(j, subMenu){
$(subMenu).children('li').each(function(i, li){
$(li).css('transition-delay', (i*25)+'ms')
})
});

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>

Show/hide content for menu sublink and close the content when click next new link

I'm looking for a solution, it must work in IE also, that I can have the content hidden and then when you click one of the menu items it shows the content. However, the content doesn't hide until a user clicks on the next link...
Please check this link
http://jsfiddle.net/varada/YLX9x/
you can use jquery hide() and show() functions for that.
Let the id of div that is to be hidden be hidden_div, let menu item be menu_item, next button be next,
Import the jquery.js
and write the ready function as below..
$(document).ready(function() {
$('#menu_item').click(function() {
$('#hidden_div').show();
});
$('#next').click(function() {
$('#hidden_div').hide();
});
});
or if you mean the content be visible till he click the next link on the menu item, add a class name say, menu_class to the menu items and write the code
$('.menu_class').click(function() {
$('#hidden_div').hide();
});
instead of $('#next').click(function()
if you have a menu like
<ul>
<li class='menu_class'>item 1</li>
<li id='menu_item' >item 2</li>
<li class='menu_class'>item 3</li>
</ul>
and the div
<div id='hidde_div' style='display:none'>
content
</div>
then if you click item 2 the div will get displayed. and if you click item 1 or item 3 it will get hidden. make sure you are using the code $('.menu_class').click(function() {
html:
<li class="main">Web
<ul>
<li>Designing</li>
<li>Development</li>
</ul>
</li>
<li class="main">IT
<ul>
<li>Sales & Service</li>
<li>CCTV</li>
<li>DVR</li>
</ul>
</li>
<li class="main">ITES
<ul>
<li>BPO</li>
<li>Online Portal</li>
<li>Online Marketing</li>
</ul>
</li>​
js:
$(document).ready(function(){
$('li ul:not(:first)').hide();
$('ul li').click(function(){
$(this).closest('.main').next().find('ul').show();
$(this).closest('ul').hide();
});
});​
http://jsfiddle.net/7QheB/

Categories