Problems with JavaScript Dropdown Nav - javascript

I am using a JavaScript drop down navigation menu that I found after some Googling and I've managed to style it the way I want. However, after validating my site, I get errors with the ul tags (Error: Element ul not allowed as child of element ul in this context. (Suppressing further errors from this subtree.)). Not only do I get this error, the navigation doesn't work the way it should. I've tried different variations of the ul and li tags, and moved things around, and I still cannot get it to work correctly.
<div class="nav">
<ul id="menu" class="menu">
<li>One
<ul>
<li class="submenu">
One
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</li>
<li class="submenu">
<li>Two</li>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</ul>
</li>
<li>Two
<ul>
<li class="submenu">One</li>
<li class="submenu"><li>Deny</li>
<ul>
<li class="noborder">One</li>
<li>Two</li>
<li>Three</li>
</ul>
</ul>
</li>
<li>Three
<ul>
<li class="submenu">
One
</li>
</ul>
</li>
<li>Four
<ul>
<li class="submenu">
One
</li>
</ul>
</li>
</ul>

I am not sure is this is the problem with your java script code. But the mismatch in writing of these html tags also may cause these kind of problems. Please check the opening and closing tags once again and make sure those are in the correct position or not. When i gone through your html code i found some mismatch in the tags. One is-
your FIRST menu item Two are written in between two li /li tags. But your FIRST One menu item are NOT in between these li /li tags.

Close your parent div tag and see if that helps
also this...
<li class="submenu">
<li>Two</li>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</ul>
</li>
...probably needs re-work because you are nesting an li tag before creating a child ul tag. You just to need to learn how to properly nest ul and li tags. Here is a discussion I found on stackoverflow that talks about a similar issue.
Once you get your HTML correct, the javascript process should be easier to manage.
Hope that helps.

Related

How to click on a <li> <a/> </li> button in Javascript only?

I want to click on a button like this using Pure javascript:
<ul>
<li class="inactive-link">Schedule Appointment</li>
<li class="inactive-link">Schedule Appointment</li>
</ul>
Try
<ul>
<li class="inactive-link">Schedule Appointment</li>
<li class="inactive-link">Schedule Appointment</li>
</ul>
The question is pretty unclear regarding what you're trying to achieve but for the js part use
document.querySelector(".inactive-link a").addEventListener('click',()=>{
window.location="appointment?q=q8345lbf3r9tcmgMnfsad"
})
Adds the click event to the first li>a element (You can add it to all using forEach). This produces an equivalent result.

jQuery iterate nested html list

I have a HTML code of nested list giving me a hard time to read with jQuery!
I'm using
$.get();
to get the html then using
$(data).find(".thelist ul");
To get the list only which looks like
<ul>
<li>Draft Page
<ul>
<li>Batch Version 7</li>
</ul>
</li>
<li>info Control System
<ul>
<li>About info</li>
</ul>
<ul>
<li>Application
<ul>
<li>Functionality
<ul>
<li>
Access
</li>
</ul>
<ul>
<li>Login
</li>
</ul>
<ul>
<li>info Desktop
</li>
</ul>
<ul>
<li>Search
</li>
</ul>
<ul>
<li>info Mobile
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>Support</li>
</ul>
<ul>
<li>Technical Manual
<ul>
<li>Formatting
</li>
</ul>
<ul>
<li>Troubleshooting</li>
</ul>
</li>
</ul>
</li>
</ul>
The actual list is more than 200 item! and it can go up to 7 levels!
What im getting is every item that has children the text is including all of their text!.
I need to get the text and the link of each then append or generate my own list with same level but different html structure
Is this the best approach ?
I have tried iterating using $each()
try this it will give all titles with links.
$(function(){
var links = [];
$( "ul" ).find( "a" ).each(function(k,v){
links.push({ title : $(v).text(), link : $(v).attr('href'), level : $(v).parents('ul').length });
});
console.log(links);
});
Assuming the <ul> you've shown above is the one inside the .thelist block.
I think it'll be easier if you just use $(data).find(".thelist ul li") to get all the list items inside the <ul> element (and subelements).
Or, if you want to go down just one level, you can do $(data).find(".thelist ul>li").
And, you can use the following method to avoid selecting children nodes:
$("#foo")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text();
I got this removing children idea from here.
I hope this helps.

jQuery - known class of child: find next descendent of parent in top (from parent ID)

I've been searching a lot for this, without any solution so far. As you might also have seen the topic title might be a little hard to interpret and that's because I'm not quite sure how to explain it shortly.
The problem
Looking at the HTML below, I know the class of the last element called "active" and this element is chosen dynamically in jQuery, based on which site the visitor is on currently - i.e. different elements has this class depending on the site. On another site the li with class first-sub-li could have the class active (or for that matter the li with class first). This class is, as said, added dynamically based on the site with jquery. From here on I wish to identify the parent of the element with active which is a direct descendent of top-parent and add a class called active-parent to this. I.e. in the case below i wish to add the active-parent class to the li with class second.
EDIT: Please note that the "depth" of the list can vary, therefore also requiring a "dynamic" approach to picking out the parent. I completely forgot this in the initial writing.
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li"></li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li">
<ul class="second-sub-sub-ul">
<li class="second-sub-sub-li active"></li> <!-- Here -->
</ul>
</li>
</ul>
</li>
</ul>
So far I've tried the following jQuery without succes as it doesn't identify it.
EDIT 2: This actually does work, but initially it didn't as it apparently was called before the class was loaded, despite appearing later in the javascript document. Wrapping it in a $(window).on("load", function() solves the problem as shown below.
$(window).on("load", function() {
$(".active").closest("#top-parent > li").addClass("active-parent");
});
The original code was just $(".active").closest("#top-parent > li").addClass("active-parent");
You can start traversing up with .parent(), it will excluding the self li.
$(".active").parent().closest("li").addClass("active-parent");
You can use :has() selector
$('#top-parent > li:has(.active)').addClass("active-parent");
$('#top-parent > li:has(.active)').addClass("active-parent");
.active-parent {
background-color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li"></li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li">
<ul class="second-sub-sub-ul">
<li class="second-sub-sub-li active"></li>
<!-- Here -->
</ul>
</li>
</ul>
</li>
</ul>
I think this is what you're looking for. Find all li which are direct descendants of topmost-parent and filter that for the one which has a child .active. Apply the class.
$('#top-parent > li').filter(function(e){
return $(this).find('.active').length>0;
}).addClass("active-parent");
.active-parent{background-color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li">1.1</li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li active">2.1</li> <!-- Here -->
</ul>
</li>
</ul>

How to add Dropdown arrow to a <li> which has child elements

This is my original menu.
<ul class="mymenu">
<li>1 HTML </li>
<li>2 CSS
<ul>
<li>3.1 jQuery
<ul>
<li>3.1.1 Download</li>
<li>3.1.2 Tutorial</li>
</ul>
</li>
</ul>
</li>
<li>3 Javascript </li>
</ul>
I want to convert it into
<ul class="mymenu">
<li>1 HTML </li>
<li>2 CSS <span class="parent">&#9660</span>
<ul>
<li>3.1 jQuery
<ul>
<li>3.1.1 Download</li>
<li>3.1.2 Tutorial</li>
</ul>
</li>
</ul>
</li>
<li>3 Javascript </li>
</ul>
The difference between two menu is,
<span class="parent">&#9660</span>
I want to add dropdown arrow to the each element which has submenu.
I want Jquery or javascript solution.
I will provide two solutions to the problem.
1). Javascript solution. Using jQuery you can achieve it pretty easy:
$('a + ul').prev('a').append('<span class="parent">&#9660</span>');
Demo: http://plnkr.co/edit/37k1KMpqJ6G2tPrvprBa?p=preview
2). CSS only solution. Using modern pseudo selectors you can do this:
li a:not(:only-child):after {
content: '\25bc';
}
Additional info: :only-child and :not selectors. Support: IE9+.
Note: CSS solution is not equivalent to javascript one, as it doesn't insert span.parent element in DOM.
Demo: http://plnkr.co/edit/sfoctCWzjRCBlXG9dVyD?p=preview

jQuery accordion issue with template markup

I'm having a little issue with this accordion script.
And I know why it's happening but I can't fix it. And I'm not sure it's possible to fixed it?
The accordion script i'm using is this and it's very easy to implement. http://www.i-marco.nl/weblog/jquery-accordion-menu/
The mark-up for this accordion is simple and semantic.
<ul class="menu">
<li>
Link
<ul class="acitem">
<li>PivotX</li>
<li>WordPress</li>
<li>four</li>
<li>Textpattern</li>
<li>Typo</li>
</ul>
</li>
<li>
Weblog Tools
<ul class="acitem">
<li>PivotX</li>
<li>WordPress</li>
<li>four</li>
<li>Textpattern</li>
<li>Typo</li>
</ul>
</li>
<!-- and so fourth -->
</ul>
This is the style of the markup that the script if designed to work with. And it works, see here... http://jsfiddle.net/motocomdigital/CzZqZ/1/
But my problem is because I'm working with a template that I can't change the mark-up of, see my outputted markup below.
<ul class="menu">
<ul>
<li>
Link
<ul class="acitem">
<li>PivotX</li>
<li>WordPress</li>
<li>four</li>
<li>Textpattern</li>
<li>Typo</li>
</ul>
</li>
</ul>
<ul>
<li>
Weblog Tools
<ul class="acitem">
<li>PivotX</li>
<li>WordPress</li>
<li>four</li>
<li>Textpattern</li>
<li>Typo</li>
</ul>
</li>
</ul>
</ul>
This the mark up that is outputted which is stupid.
Its outputting more than it needs to.
I've created a js fiddle for the markup above so you can see what is happening http://jsfiddle.net/motocomdigital/CzZqZ/2/
It's not closing the others when a new one is opening...
Does anyone know how to fix the script so it work like the first jsfiddle, but with the crazy markup above?
Thanks very very much if anyone can help.
Josh
Inside the click handler, change to: var parent = this.parentNode.parentNode.parentNode;. With this it works as the other example you posted.
Add the class 'noaccordian" to your "ul" elements that you want to expand/collaspse on.
Example:
<ul class="menu">
<ul class="noaccordion">
<li>
Click Here
<ul class="acitem">

Categories

Resources