Jquery - Clickable dropdown menu - javascript

I am having an issue with my dropdown menu. I have the dropdown portion of the menu working, but when I click on a main navigational link it unveils all the list items instead of unveiling the ones relevant to the parent ul.
I have uploaded the file to jsfiddle.Could you please help me out: http://jsfiddle.net/7rwhP/1/
<div id="secondary-nav"><!--secondary-nav-->
<ul>
<li>Current Article
<ul>
<li>Example 1</li>
</ul>
</li>
<li>Past Articles
<ul>
<li>Example 1</li>
<li>Example 2</li>
<li>Example 3</li>
</ul>
</li>
<li>Tradition
<ul>
<li>Example 1</li>
<li>Example 2</li>
<li>Example 3</li>
</ul>
</li>
</ul>
</div><!--/secondary-nav-->

You need to modify your JavaScript so you aren't triggering the slideToggle on all ul ul items, and you need to add the click listener to an li - using #secondary-nav ul will trigger that click event for any item you click within that list.
Try this:
$(document).ready(function(){
$("#secondary-nav li").click(function(){
//slide up all the link lists
$(this).children('ul').slideToggle();
})
})
Remember, selectors in jQuery are just like CSS selectors. When you bind the click event to #secondary-nav ul, it will be triggered when you click anywhere in that list, because all of the list items are indeed children of the ul. Your original click handler #secondary-nav ul ul says "toggle all lists that are a child of a list", but you more pointedly wanted to achieve "toggle the list that is a child of the clicked list item".
DEMO

you should use $(this).children()
DEMO
$(document).ready(function(){
$("#secondary-nav li").click(function(){
//slide up all the link lists
$(this).children('ul').slideToggle();
})
});
You should add this css too
#secondary-nav ul li {
white-space:nowrap;
}
DEMO :After applying above css

Related

Link 'active' state on two separate HTML elements

I'm trying to mirror the 'active' state on two unordered lists using jquery/javascript. The first list is a slider/carousel and the 2nd list will be navigation links.
E.g.
<ul class="carousel">
<li class="active">Slider 1</li>
<li>Slider 2</li>
<li>Slider 3</li>
<li>Slider 4</li>
</ul>
<ul class="nav">
<li class="active"><a href'#">Link 1</a></li>
<li><a href'#">Link 2</a></li>
<li><a href'#">Link 3</a></li>
<li><a href'#">Link 4</a></li>
</ul>
So, the idea is that when the active state of the <li> in the carousel changes, so does the corresponding <li> in the 'nav' list.
Any help would be greatly appreciated.
I've created a working example here: https://jsfiddle.net/aj68mogk/14/
It was not working for you on JSFiddle because the script does not change the carousels .active class, thats done by the wp plugin.
I've put in a link to "fake" the action the plugin does (changing the carousel state).
There was a mistake in the part of code wich gets the index of the active carousel li.
So please ignore the code of my first answer and take the one of the JSFiddle. But dont forget to remove the fake link and its click function when using this on your page
Next thing is you have to select a Jquery version on JSFiddle, otherwise the $(document).ready() function is never entered, because its not pure js.
Hope this helps, if there are questions left, just leave a comment
I worked something out from several SO posts:
$(document).ready(function() {
$('.carousel').bind('DOMSubtreeModified', function(e) {
$(".nav>li.active").removeClass("active");
$(".nav>li").eq($(".carousel").index($("active"))).addClass("active");
});
});
Just add this to your Javascript and its done.
What it does: First you bind any DOM-Changes (you've said it's changed by a wp plugin or so) in the .carousel element to a new function. Inside the function you remove the active li tag, then you pick the index of the active carousel element and add the .active tag to the nav element with the index from the .carousel
Hope this helps
EDIT: There was a mistake in the code, some unneccesary line i kept in from testing. Please take the updated code
If you don't have access to the code of Wordpress plugin you have no direct way to do it , but can use a setTimeOut function. This is not the cleanest of the approaches , but I guess there is no other option.
setInterval(function() {
if ($(".carousel li").hasClass("active")) {
var active = $(".carousel").find(".active");
var index = $(active).index();
index = index + 1;
$(".nav li:nth-child(" + index + ")").addClass("active");
}
}, 1000);
.active {
color: red;
}
.active a {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="carousel">
<li class="">Slider 1</li>
<li class="active">Slider 2</li>
<li>Slider 3</li>
<li>Slider 4</li>
</ul>
<ul class="nav">
<li class="">
Link 1
</li>
<li>Link 2
</li>
<li>Link 3
</li>
<li>Link 4
</li>
</ul>

jquery navigation always opens the first option

I have a nav element which is something like this:
<ul>
<li name='first_item'>
<ul>
<li>item 1</li>
<ul>
<li>item 1.1</li>
<li>item 1.2</li>
</ul>
<li>item 2</li>
</ul>
</li>
</ul>
<ul>
<li>
<ul>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
</ul>
and the code that handles the the sliding down and up is:(nav is a html element which is a parent of above)
nav.find("li").each(
if ($(this).find("ul").length > 0) {
_callback = false;
$("<span>").text("^").appendTo($(this).children(":first"));
//show subnav on hover
$(this).mouseenter(function() {
$(this).find("ul").stop(true, true).slideDown();
});
//hide submenus on exit
$(this).mouseleave(function() {
$(this).find("ul").stop(true, true).slideUp();
});
}
});
what happens is when I hover over the first_item it opens the sub menus and after it's finished sliding down them, it will open item 1's sub menus as well. I'm totally lost over this. Any help would be appreciated.
First of all, it seems you copyied the jquery without the function, so that isnt the problem:
nav.find("li").each(function(){
I think the problem is, that you travel to deep, so try this:
$(this).find(">ul")
or this:
$(this).children("ul")
From jQuery:
The .children() method differs from .find() in that .children() only travels a single level down the DOM tree while .find() can traverse down multiple levels to select descendant elements (grandchildren, etc.) as well.

jQuery .click() .show() function issues

Could anyone please let me know what i'm doing wrong.
I have:
//My HTML
<div>
<ul>
<li id="test">Main Item 1</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<li>Main Item 2</li>
<li>Main Item 3</li>
</ul>
</div>
//My CSS
.list-in-list {
display:none;
}
//My jQuery
$(document).ready(function() {
$('#test').click(function() {
alert("hello");
});
});
My final goal is to show that none displayed content if you press a list item, so that it expands neatly. However, i can't seem to get that alert() appearing in any way. Should i use an id for all list items in the main list, or is it enough with a class?
/W
you can add .next function to show next ul for any li curreny click by user. you have to change id test to one class name to make effect in all click of main li
HTML would be like
<div>
<ul>
<li class="main">Main Item 1</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<li class="main" >Main Item 2</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<li class="main">Main Item 3</li>
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</ul>
</div>
and JQuery function is below
$(document).ready(function() {
$('.main').click(function() {
$(this).next(".list-in-list").slideToggle();
});
});
for detail you can check link
Should i use an id for all list items in the main list, or is it enough with a class?
IDs are unique. Your JavaScript code will not work properly if you have multiple identical IDs. If you're planning on adding a similar attribute to all of your list items you'd use a class in this case (and reference it with . instead of #). In this case you'd call the click function using:
$('li.myClass').click(...);
If you only have one list, however, you can simply add the ID to the ul and use the click function as:
$('ul#myId > li').click(...);
Note that it would be marginally quicker with the classes in this case.
You'd then reference your inner ul using:
$('li.myClass > ul.list-in-list');
Or, depending on which of the above you went with:
$('ul#myId > li > ul.list-in-list');
(You'd use > here to select only the direct child. If you used ul#myId li you'd also be selecting the li elements which belong to any inner ul)
Your code works fine I do believe you have not included Jquery on your page - or maybe the path to it is not valid. Check your network tab to see if you get an http error retrieving jquery.
You can show the hidden li by doing the following:
$(document).ready(function() {
$('#test').click(function(e) {
$(this).find('.list-in-list').show();
});
});
Your code works fine:
Demo
In this case classes would be better than ids because Id's have to be unique on your page. You can use classes like in the demo below by adding a class to your outer li elements. Just change the binding from #test to whatever class you give your li elements.
$('.clickAbleLi').click(function(e) {
$(this).find('.list-in-list').show();
});
Demo
You close your </li> tag before your "list-in-list". You should close your </li> tag after your inside list ;) Like this :
<div>
<ul>
<li id="test">Main Item 1
<ul class="list-in-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>Main Item 2</li>
<li>Main Item 3</li>
</ul>
</div>
It sholud work but Try moving the ID attribute to the A instead of LI if you experience problems

change class on LI click

I need to dinamically assign a .selected class to the element where I click and also remove any other previous class asigned to the clicked element so I can change CSS class. Maybe this code:
$(this).click(function(){
$(this).addClass('selected');
});
works but what happend if I click in any other LI? Any help to get this work?
EDIT:
Ok see this code:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
By default none have any classes but I click in Item 2 then the HTML should transform on this one:
<ul>
<li>Item 1</li>
<li class="selected">Item 2</li>
<li>Item 3</li>
</ul>
but once again if I click in Item 3 then the HTML should transform on this one:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li class="selected">Item 3</li>
</ul>
This is what I'm trying to do
I'd suggest:
$(selector).click(function(){
$('.selected').removeClass('selected');
$(this).addClass('selected');
});
With regards to the comment left by moonwave99 (below), if you only want to remove the selected class-name from those elements contained within the same parent element:
$(selector).click(function(){
var that = $(this);
that.parent().find('.selected').removeClass('selected');
that.addClass('selected');
});
Though it's worth remembering what element you're clicking, and what the parent will be, for example, clicking on the a in the following HTML:
<ul>
<li>link text</li>
</ul>
Will look within the li for the other .selected elements, and so you should use:
$(selector).click(function(){
var that = $(this);
that.closest('ul').find('.selected').removeClass('selected');
that.addClass('selected');
});
First remove selected class from all li inside ul and then apply class to clicked li.
$('ul li').click(function(){
$('ul li').removeClass('selected');
$(this).addClass('selected');
});
On my travels I discovered that it is not possible to addClass of 'active' to list items in when using bootstrap. So if you are reading this (as I was) wondering why this doesn't work when the classname is 'active' you need to choose something else.

How do I include all children of a DOM element to be dragged using the Sortable plugin for MooTools?

I am using mootools-more.1817.js...this is my HTML structure:
<ul id="categories">
<div id="admin">Admin Controls</div>
<li class="selected">Test
<ul>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Test 2
<ul>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Top Links
<ul>
<li id="article">Link 1</li>
<li id="article">Link 2</li>
<li id="article">Link 3</li>
<li id="article">Link 4</li>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Lame Links
<ul>
<li id="article">Link 9</li>
<li id="article">Link 10</li>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Awesome Links
<ul>
<li id="article">Link 11</li>
<li id="article">Link 12</li>
</ul>
</li>
</ul>
So I want to do two things:
Be able to drag each li item to another section and have it take all its children with it. E.g. if I am dragging the li that has the link Top Links, I want to drag not only the words Top Links, but also the div#admin, ul and li that are children of that parent li. Essentially all the children of each li.
I would also like to be able to drag items between lists of the children. So for instance, say I want to drag the link Link 2 from that ul to the section called Awesome Links and drop it between the links Link 11 and Link 12.
I have done this:
window.addEvent('domready', function(){
new Sortables('#categories', {
clone: true,
revert: true,
opacity: 0.7
});
});
What that does is drags JUST the li, and not the children of the li.
How do I achieve those?
Thanks.
First, you have invalid HTML by having div items in your categories list that are not in li tags themselves. The only immediate children to a ul can be li for a valid list.
Second, according to the documentation, "To enable sorting between lists, one or more lists or id's must be passed using an array or a selector" (http://mootools.net/docs/more/Drag/Sortables). That means, to move items between your sublists, each ul must be passed into a sortables group (different than the categories group). This should solve your issue #2.
I'm not yet sure why it would not drag the whole contents of the li, though it may be the invalid HTML is causing issues.

Categories