Displaying li when clicking on item - javascript

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

Related

Reverse children elements with jQuery

I need to reorder some children elements with defined class and maintain the old order of the others that doesn't have the class. I have other sub elements
Code - html
<ul class="menu_dinamico">
<li class="reverseMenu">Item 1</li>
<li class="reverseMenu">Item 2</li>
<ul>
<li>item 2.1</li>
<li>item 2.2</li>
</ul>
<li class="reverseMenu">Item 3</li>
<li class="reverseMenu">Item 4</li>
<li>Item 4.5</li>
<li>Item 5</li> </ul>
Code - javascript
$.fn.reverse = [].reverse;
var list = $('.menu_dinamico');
var listItems = list.children('.reverseMenu');
list.prepend(listItems.get().reverse());
The result
item 4
item 3
item 2
item 1
item 2.1
item 2.2
item 4.5
item 5
The result wanted
item 4
item 3
item 2
item 2.1
item 2.2
item 1
item 4.5
item 5
P.s: I have to maintain the html structure like links, attributes etc.
Any clues? Thanks!
Edit:
After #bubicsaszar response I realized that my question was incomplete because my list can have infinite sub lists and their structure must be preserved.
try this, if the constant items always in the end of the list:
$.fn.reverse = [].reverse;
var list = $('.menu_dinamico');
var listItems = list.children('.reverseMenu');
list.prepend(listItems.get().reverse());

Using jQuery with collapse menu

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){}

How do I make this jQuery not count sublists within a list?

I would like to know how many "root" steps are in an HTML list. I am going to be iterating through the root steps but the sub-steps are to be completely ignored.
My jQuery always counts the root <li> steps as well as the child <li> steps, but all I want is the root.
Fiddle: https://jsfiddle.net/5x33omaw/1/
I want it to count only 3 steps instead of the 5 that it returns. How do I ignore the children?
HTML:
<ol id="sidebar-step-list" class="no-indent">
<li>Step 1</li>
<li>Step 2
<ul>
<li>Substep 1</li>
<li>Substep 2</li>
</ul>
</li>
<li>Step 3</li>
</ol>
<hr/>
<div id="dog"></div>
JavaScript/jQuery
var stepList = $("#sidebar-step-list li");
var length = stepList.length;
$("#dog").text("Number of steps: " + length);
just add > sign
var stepList = $("#sidebar-step-list > li");
by adding > will give you the direct li of #sidebar-step-list
DEMO

Get <li> with child <ul> from <ul> child of <li>

I have a very simple example of a menu here:
<ul id="1">
<li>First</li>
<li>Second
<ul id="2">
<li>Second - 1</li>
<li>Second - 2</li>
<li>Second - 3
<ul id="3">
<li>Aaa</li>
<li>Bbb</li>
<li>Ccc</li>
</ul>
</li>
</ul>
</li>
<li>Third</li>
</ul>
I need to get the <li> that has a child <ul> and that is a child of <ul> who is a child of <li>, and apply a style to it.
I know it sounds complicated, but in the example above I want to get only the <li> that says "Second - 3" which is inside a ul, which is a child of a li and has a child ul. I don't want to get any other <li>s.
I can't do this without getting also the li which says "Second", and I don't want that.
$("li > ul").addClass('whatever');
Use $("li ul li:has(ul)")
e.g:
$(function(){
var items = $("li ul li:has(ul)");
alert(items.html());
});
Working example: http://jsfiddle.net/EXzaa/
Try this:
$("li > ul > li").each(function(){
if ( $(this).find("ul").length > 0){
$(this).css({"font-weight":"bold"});
}
});
Unless I get you wrong this is simple. Try something like this:
$('#3').parent('li').addClass('whatever');
This will select the parent node of the ul element with the id = 3 (only if it is an li element)

How to get previous <li> when the li's are wrapped inside <ol>?

How do i get the previous li when it is wrapped inside an ol?
I have used the following script, but it doesnt seem to work:
<script type="text/javascript">
$(document).ready(function () {
$(".categoryitem").click(function () {
alert("hihi");
$(this).parent().prev("li").css('background-color', 'red');
$(this).prev("li").css('background-color', 'red');
});
});
</script>
This is how the HTML looks like (In my real application i have set the class name on each li, but didnt do it in this example)
<ul>
<li>
Item 1
</li>
<ol>
<li>
Item 1.1
</li>
</ol>
<li>
Item 2
</li>
<ol>
<li>
Item 2.1
</li>
<ol>
<li>
Item 2.1.1
</li>
</ol>
<ol>
<li>
Item 2.1.2
</li>
</ol>
<ol>
<li>
Item 2.1.3
</li>
</ol>
<ol>
<li>
Item 2.1.4
</li>
</ol>
</ol>
</ul>
When i click on Item 1.1, the parent 1 becomes red
When i click on item 2, nothing happens, but i would like 1.1 to become red
When i click on items 2.1.1, 2.1.2, 2.1.3, 2.1.4 nothing happens
When i click on item 2.1, the parent 2 becomes red
I would like all previous LI's to become red, even if they are in higher levels
What am i doing wrong?
This is the method that creates the tree:
EDIT: I changed ol to ul, for each group
<ul>
#{
foreach(var cq in Model) {
#ShowSubItems(cq);
}
}
</ul>
#helper ShowSubItems(MvcApplication3.Models.ViewModels.Category.AllQuestionsInCategoriesViewModel MyObj)
{
<li class="categoryitem" categoryid="1">#Html.ActionLink(MyObj.Category_Number + " " + MyObj.Category_Name, "DisplayQuestions", new { categoryId = MyObj.Category_ID, page = 1 })</li>
if (MyObj.SubCategories != null && MyObj.SubCategories.Count != 0)
{
<ul>
#foreach (var subitem in MyObj.SubCategories)
{
#ShowSubItems(subitem)
}
</ul>
}
}
</ul>
To get the CLOSEST PARENT, you can simply use .closest()
<ul>
<li>
Click Me!
</li>
</ul>
$(document).ready(function() {
$('a.clickme').click(function() {
$(this).closest('li').css('background-color', 'red');
});
});
Here's the jsfiddle source of this example: http://jsfiddle.net/y36qg/

Categories

Resources