Currently my side menu consists of parent and child pages. To keep the menu expanded on the child page I am having to use a switch statement and check if the url is what I am looking for and if it matches show the expanded child items.
$(function () {
var url = window.location.pathname;
switch (url) {
case 'Path1':
$('#ChildOne').show();
break;
case 'Path2':
$('#ChildTwo').show();
break;
case 'Path3':
$('#ChildThree').show();
break;
...
}
});
I've got over 20 pages where I need to display the child elements. My question is, is this the only way or does someone know a better way? Thanks in advance for your help.
Note
I only want to display the relevant child elements on active child page. Suppose, I click on ChildOne when I get redirected to that page I only want to see the child elements under that parent.
My mark-up is as follows
<ul>
<li class="parent"><a style="cursor: pointer;">Parent One</a>
<ul class="child" id="ChildOne">
<li>Child Of Parent One</li>
<li>Child Of Parent One</li>
</ul>
</li>
<li class="parent"><a style="cursor: pointer;">Parent Two</a>
<ul class="child" id="ChildTwo">
<li>Child Of Parent Two</li>
<li>Child Of Parent Two</li>
<li>Child Of Parent Two</li>
</ul>
</li>
<li class="parent"><a style="cursor: pointer;">Parent Three</a>
<ul class="child" id="ChildThree">
<li>Child Of Parent Three</li>
<li>Child Of Parent Three</li>
</ul>
</li>
...
</ul>
I have added some code in order to be able to reproduce the issue. I added some classes to the parent items of the menu so that I can check them later in order to hide or not their children. The class names are the page name (final word on the url) which is unique. I get it using the substring method.
In this example, your current page is the second option, and by using the each() function of jquery, you can go through the elements without having a ton of switch cases or if statements.
Fiddle
Code snippet:
function escocha() {
var url = '/about/profile'
var n = url.lastIndexOf("/");
var myClassName = url.substring(n + 1, url.length)
alert("The url: " + url);
alert("The class name: " + myClassName);
$(".child").each(function (index) {
alert(this.id);
if (this.className.indexOf(myClassName) > -1) { // if any class name for this element contains the string 'display'
alert("I am the current page so my menu items won't collapse!");
} else {
$('#' + this.id).hide();
}
});
}
$("#esmaga").click(function () {
escocha();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="parent"><a style="cursor: pointer;">Parent One</a>
<ul class="child display" id="ChildOne">
<li>Child Of Parent One
</li>
<li>Child Of Parent One
</li>
</ul>
</li>
<li class="parent"><a style="cursor: pointer;">Parent Two</a>
<ul class="child profile" id="ChildTwo">
<li>Child Of Parent Two
</li>
<li>Child Of Parent Two
</li>
<li>Child Of Parent Two
</li>
</ul>
</li>
<li class="parent"><a style="cursor: pointer;">Parent Three</a>
<ul class="child display" id="ChildThree">
<li>Child Of Parent Three
</li>
<li>Child Of Parent Three
</li>
</ul>
</li>...</ul>
<button id="esmaga">Esmaga</button>
you can use id of ULs elements same as window.location.pathname. In this case you can call:
try{
$("#"+window.location.pathname).show();
}catch(e){
// error handling
}
but your menu is strange ;)
OK, one more version with object
var oPath = new Object({
"Path1":"ChildOne",
"Path2":"ChildTwo",
"Path3":"ChildThree"
});
try{
$("#"+ oPath[window.location.pathname]).show();
}catch(e){}
Related
I have weird structure and want to disabled first element inside li.expanded using a[href="/abc"]. I have parent and child have same href and title is different. How can I select parent only element?
Here the code:
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">xyz-parent</li>
<li class="leaf">pqr</li>
<li class="last expanded">abc //want to find this element and apply treatment
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">abc</li> //not this one
<li class="last leaf">mno</li>
</ul>
</li>
</ul>
What I have tried, the function is working. it's selecting both a[href="/abc"] parent and child. I want to find and select only parent one.
openabcInNav: function() {
var navEl = $('#main-menu, #main-right-menu li.expanded').find('a[href="/abc"]:nth-child(1)');
navEl.addClass('doNotClose');
navEl.on('click mouseover', function(event) {
event.preventDefault();
$('nav.global-nav').find('li.expanded').toggleClass('show');
});
},
You could use the :first selector that will return the first occurrence what it the parent :
$('ul>li.expanded>a[href="/abc"]:first')
$('ul>li.expanded>a[href="/abc"]:first').css('background-color', 'green');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">xyz-parent</li>
<li class="leaf">pqr</li>
<li class="last expanded">abc //want to find this element and apply treatment
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">abc</li> //not this one
<li class="last leaf">mno</li>
</ul>
</li>
</ul>
a[href="/abc"]:nth-child(1) looks at first child object inside a[href="/abc"]
Try using:
a[href="/abc"]:nth-of-type(1)
This will return the first that matches a[href="/abc"]
I have following design of a ul list.
<ul>
<li class="category">
Design
<ul>
<li>Graphic Design</li>
<li>Web Design </li>
<li>HTML</li>
<li>CSS</li>
<li>Print</li>
</ul>
</li>
<li class="category">
Development
<ul>
<li>PHP</li>
<li>Java</li>
</ul>
</li>
</ul>
Now what I want is if you click on the "CSS" item ,I want to get the text of its parent i.e "Design".
I have tried the following code but I got the whole list in it.
$('ul').on("click", "li", function (e) {
console.log("Child Clicked: "+$(this).text()+" Parent: "+$(this).parents(".category").text());
});
Try replacing this part
$(this).parents(".category").text()
with
$(this).parents(".category")[0].childNodes[0].textContent;
childNodes returns all the child elements including text nodes.
If you want to use jQuery only, then wrap this textnode inside a span
<ul>
<li class="category">
<span>Design</span>
<ul>
<li>Graphic Design</li>
<li>Web Design </li>
<li>HTML</li>
<li>CSS</li>
<li>Print</li>
</ul>
</li>
<li class="category">
<span>Development</span>
<ul>
<li>PHP</li>
<li>Java</li>
</ul>
</li>
</ul>
and fetch that first node's text using
$(this).parents(".category span").html()
Another approach could be to use contents and filter of jquery
$(this).parents(".category").contents().filter(function() {
return this.nodeType == 3;
}).nodeValue;
just change :
console.log("Child Clicked: "+$(this).text()+" Parent: "+$(this).parents(".category").text());
with :
console.log("Child Clicked: "+$(this).text()+" Parent: "+$(this).parent().text());
Ive got a <ul> list that is nested inside of a parent <ul> the child is hidden, i want to show it when a link is clicked in its parent. At the same time i want the parent <ul> content to be hidden (without hiding the child).
I know i could work around this by having two separate <ul> lists that were un nested but Ive been trying to keep them nested following the W3 guidelines on nested lists.
The issue Im having at the moment is that when the main list is hidden it also hides the child and does not allow it to be shown.
Ive made a jsfiddle of the issue here - http://jsfiddle.net/xc0g770z/
The HTML Im using is
<ul id="main-list">
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
<li>FOUR</li>
<li>FIVE</li>
<li>SIX
<ul id="sub-nav">
<li>SIX - ONE</li>
<li>SIX - TWO</li>
<li>SIX - THREE</li>
<li>SIX - FOUR</li>
<li>RETRUN</li>
</ul>
</li>
<li>SEVEN</li>
<li>EIGHT</li>
</ul>
The jQuery Im using is
$("#open-submenu").click(function () {
$("#main-list").hide();
$("#sub-nav").show();
});
Any ideas how i could get this to work whilst still using the nested ?
DEMO: http://jsfiddle.net/murid/xc0g770z/1/
$("#sub-nav").hide();
$("#open-submenu a").click(function () {
$("#main-list li").hide();
$("#open-submenu").show();
$("#sub-nav").show();
$("#sub-nav li").show();
});
One way to do this would be to use class
<ul>
<li class="main-list">ONE</li>
<li class="main-list">TWO</li>
<li class="main-list">THREE</li>
<li class="main-list">FOUR</li>
<li class="main-list">FIVE</li>
<li class="main-list" id="open-submenu">SIX<li></a>
<li class="six-sub">SIX - ONE</li>
<li class="six-sub">SIX - TWO</li>
<li class="six-sub">SIX - THREE</li>
<li class="six-sub">SIX - FOUR</li>
<li class="six-sub">RETRUN</li>
<li class="main-list">SEVEN</li>
<li class="main-list">EIGHT</li>
</ul>
The in the jquery
$("#open-submenu").click(function () {
$(".main-list").hide();
$(".six-sub").show();
});
I am beginner in javascript. I have this list:
<p class="lead">parent item1</p>
<ul class="list bot-2">
<li>child item 1
</li>
<li>child item 2
</li>
<li>child item 3
</li>
</ul>
<p class="lead">parent item2</p>
<ul class="list bot-2">
<li>child item 1
</li>
<li>child item 2
</li>
<li>child item 3
</li>
</ul>
<p class="lead">parent item3</p>
<ul class="list">
<li>child item 1
</li>
<li>child item 2
</li>
<li>child item 3
</li>
</ul>
I need to display the matching div when one child item clicked, and hide other divs, the matching items is in this html structure:
<ul class="list-services">
<li class="clearfix"></li>
<li class="clearfix"></li>
<li class="clearfix"></li>
</ul>
How I can do this, I see similar posts in stackoverflow, but it didn't have the similar structure.
Well, you could use this:
$(".list a").click(function(){
var x = $(this).parents(".list").children().get();
var find = $(this).parent().get(0);
var nth = x.indexOf(find) + 1;
$(".list-services .clearfix:not(:nth-child(" + nth + "))").hide();
});
http://jsfiddle.net/wumm/v7Ks7/1/
var x = $(this).parents(".list").children().get(); gets the current .list children.
Then var find = $(this).parent().get(0); find is set to the liin which this a was.
And now nth is set to the index of this li in the current .list. (1 is added because CSS has a 1 based index)
Last thing: hiding anything else then the nth link in .list-services
This can be done with plain javascript as well, here's the jQuery solution:
$('a').on('click', function (event) {
$('.clearfix').hide();
$('.clearfix').eq($(this).closest('li').prevAll('li').length).show();
});
The $(this).closest('li').prevAll('li').length bit gives the index of the clicked child item by finding the immediate li parent and counting the number of previous li tags inside the parent ul tag. Then we just show the .clearfix item with that index using eq and show
DEMO
I have one Activity xml file and I am try to get from activity when click on activity there child display. Its look like end of the all click.
<ul id="firstLevelChild">
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
Now I want that if li have no leaf node then its display in other another div. Something like:
Click on Acitivities there have child node Physical1 and there also child Cricket and there chil One Day now one day have no child when click on one day its display in my <div id="result"></div>
I would add this as a comment, but I don't have enough rep. ChildNodes() isn't a function - since it looks like you're using jQuery, try children() instead.
I think javascript could helpr you there. A part from the fact that you first build your DOM correct ;)
The hasChildNodes() method returns TRUE if the current element node has child nodes, and FALSE otherwise.
http://www.w3schools.com/dom/met_element_haschildnodes.asp
Assuming the markup you provided is how it's going to be always i.e. ul as child for all li. You just check if ul exists inside the current li. See fiddle
HTML
<div id="content">
<ul id="firstLevelChild">
<li>
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<h2>Result</h2>
<ul id="result"></ul>
JS
$('#content li').each(function (i) {
//for display purpose only
$('#content').append('<span class="list">li(' + i + '):' + $('ul', $(this)).length + '</span>');
//the code you needed
if ($('ul', $(this)).length < 1) {
$(this).on('click', function () {
$('#result').append($(this).parent().html());
});
}
});