I have this function that expands the <ul> and hides it after it is pressed.But when i press on <li> it will also close or expand. How do I make it to toggle only when the the <h4> is clicked ?
$('.category ul').hide();
$('.sub').click(function() {
$(this).find('ul').slideToggle();
});
<ul class="category text-center">
<li class="sub">
<h4><b>Licenses</b></h4>
<ul class="archive_posts">
<li class="posts">Licence types and users plans</li>
<li class="posts">Adding new licence</li>
<li class="posts">Updating licence</li>
<li class="posts">Removing licence</li>
</ul>
</li>
</ul>
Thanks in advance.
Changes made
► changed $('.sub').click(function() { to $('.sub h4')
► changed $(this).find('ul') to $(this).next()
Working Demo
$('.category ul.archive_posts').hide();
$('.sub h4').click(function() {
$(this).next().slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="category text-center">
<li class="sub">
<h4><b>Licenses</b></h4>
<ul class="archive_posts">
<li class="posts">Licence types and users plans
</li>
<li class="posts">Adding new licence
</li>
<li class="posts">Updating licence
</li>
<li class="posts">Removing licence
</li>
</ul>
</li>
</ul>
Change the binding to the h4, then target the next ul.archive_posts for sliding.
$('.category ul').hide();
$('h4').click(function() {
$(this).next('ul.archive_posts').slideToggle();
});
See it working in this JS Fiddle: https://jsfiddle.net/rwvdf8ys/1/
Hope that helps.
The problem is $('this').find('ul').slideToggle();
'this' represents the obj that is cals the function. In this case it is h4. H4 has noe ul, so you cant find it. but you can find ul on $('.sub')
Here is ann example
$('.category ul').hide();
$('h4').click(function() {
$('.sub').find('ul').slideToggle();
});
<ul class="category text-center">
<li class="sub">
<h4 id="foo"><b>Licenses</b></h4>
<ul class="archive_posts">
<li class="posts">Licence types and users plans</li>
<li class="posts">Adding new licence</li>
<li class="posts">Updating licence</li>
<li class="posts">Removing licence</li>
</ul>
</li>
</ul>
js fiddle:
https://jsfiddle.net/8hvc4cfh/
You might use the siblings('ul') selector to find and close the neighbour ul. While $(".sub h4") limits the clickable elements to your h4.
$('.category ul').hide();
$('.sub h4').click(function() {
console.log('test');
$(this).siblings('ul').slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="category text-center">
<li class="sub">
<h4><b>Licenses</b></h4>
<ul class="archive_posts">
<li class="posts">Licence types and users plans
</li>
<li class="posts">Adding new licence
</li>
<li class="posts">Updating licence
</li>
<li class="posts">Removing licence
</li>
</ul>
</li>
</ul>
You can try this.
$('li.sub h4').click(function() {
$(this).next().slideToggle();
});
Related
I have a question on Jquery. If I click on Link1, which does not have any ul.children and the class current_page_item will be added(not shown in this code as it will be added automatically by Wordpress), then ul.children in Link2 should be hidden.
If i click on Link 2, which will have both class page_item_has_children current_page_item, in this case ul.children should be shown. I have tried my code bellow, which is i know it is absolutely wrong. Please give me your advices. Many thanks.
if($(.navigation).hasClass(page_item_has_children)){
(.navigation .page_item_has_children .children).hide();
}else if( $(.navigation).hasClass(page_item_has_children) && $(.navigation).hasClass(current_page_item)){
(.navigation .page_item_has_children .children).show();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigation">
<li>Link1</li>
<li class="page_item_has_children current_page_item">Link2
<ul class="children">
<li class="page_item">Link3</li>
<li class="page_item ">Link4</li>
</ul>
</li>
</ul>
This solution is a bit more towards your scenario (edited based on comment):
$(".navigation li").on("click", function() {
if ($(this).hasClass("page_item_has_children") && $(this).hasClass("current_page_item")) {
$(".navigation .children").show();
} else {
$(".navigation .children").hide();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigation">
<li>Link1
</li>
<li class="page_item_has_children current_page_item links">Link2
<ul class="children">
<li class="page_item">Link3
</li>
<li class="page_item ">Link4
</li>
</ul>
</li>
</ul>
How about simply hiding all nested UL elements, then simply showing the children of the clicked one?
$(".navigation li").each(function() {
// When we first load, hide all nested menus.
$(this).children("ul").hide();
if (localStorage.menuNumber) {
$(".navigation li").eq(localStorage.menuNumber).children().show();
}
})
.on("click", function() {
// When any top-level ul is clicked, hide the
// nested menus then show the current one.
$(this).parent().children().find("ul").hide();
$(this).children().show();
// We also want to persist this selection,
// should the user refresh...
localStorage.menuNumber = $(this).index;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigation">
<li>Link1
</li>
<li class="page_item_has_children current_page_item">Link2
<ul class="children">
<li class="page_item">Link3
</li>
<li class="page_item ">Link4
</li>
</ul>
</li>
</ul>
Edited it so that when it initially loads, all nested uls are hidden. Hope this helps! And edited again, to store the clicked menu in local storage. Sadly, for security reasons, this won't work here. See it as a fiddle: https://jsfiddle.net/snowMonkey/fnuvvLwb/
<ul id="ul_Book1">
<li id="li_Book1"> Book1 </li>
<ul id="ul_Chap1">
<li id= "li_Chap1"> Chapter 1</li>
<ul>
<li id="li_Sect11" > Section 1.1 </li>
<li id="li_Sect12" > Section 1.2 </li>
<li id="li_Sect13" > Section 1.3 </li>
</ul>
</ul>
<ul id="ul_Chap2">
<LI id= "li_Chap2"> Chapter 2</LI>
<ul>
<li id="li_Sect21" > Section 2.1 </li>
<li id="li_Sect22" > Section 2.2 </li>
<li id="li_Sect23" > Section 2.3 </li>
</ul>
</ul>
<ul id="ul_Chap3">
<li id= "li_Chap3"> Chapter 3</li>
<ul>
<li id="li_Sect31" > Section 3.1 </li>
<li id="li_Sect32" > Section 3.2 </li>
<li id="li_Sect33" > Section 3.3 </li>
</ul>
</ul>
function menuDisplayPath(li_id) {
var idVal = li_id;
var $obj = $('li').filter(function () { return $(this).attr('id') == idVal; }).parents();
$($obj.get().reverse()).each(function () {
if ($(this).is("li")) {
$(this).find('li').each(function () {
$(this).show();
});
$(this).find('Ul').each(function () {
$(this).show();
});
}
});
}
When a LI node is selected , say "Section 3.2" , I would like to expand/show only "Book1-- Chapter3 -- Section 3.2" and rest of the UL nodes under Book1 should not expand.
But my function menuDisplayPath(li_id) is expanding all the UL under Book1 and also display all LI's. What am I missing in the function.
Assuming all is expanded on load.
First, I corrected many missing double-quotes and extra spaces...
So here is your HTML:
<input type="reset" id="reset" value="Expand all">
<ul id="ul_Book1">
<li id="li_Book1"> Book1 </li>
<ul id="ul_Chap1">
<li id="li_Chap1"> Chapter 1</li>
<ul>
<li id="li_Sect11"> Section 1.1 </li>
<li id="li_Sect12"> Section 1.2 </li>
<li id="li_Sect13"> Section 1.3 </li>
</ul>
</ul>
<ul id="ul_Chap2">
<li id="li_Chap2"> Chapter 2</li>
<ul>
<li id="li_Sect21"> Section 2.1 </li>
<li id="li_Sect22"> Section 2.2 </li>
<li id="li_Sect23"> Section 2.3 </li>
</ul>
</ul>
<ul id="ul_Chap3">
<li id="li_Chap3"> Chapter 3</li>
<ul>
<li id="li_Sect31"> Section 3.1 </li>
<li id="li_Sect32"> Section 3.2 </li>
<li id="li_Sect33"> Section 3.3 </li>
</ul>
</ul>
</ul>
And here is the way to hide the other chapters on click of a li with a section id:
$(document).ready(function(){
$("#ul_Book1").on("click","ul ul li", function(){
$(this).parent().parent().siblings("ul").each(function(){
$(this).hide(); // Hides all other chapter
});
});
$("#reset").on("click",function(){
$("#ul_Book1").children("ul").each(function(){
$(this).show();
});
});
});
Fiddle
Now... Can't tell you how to display the <section> since I didn't see the relevant HTML.
The following worked for me:
function open($li) {
$('.content').hide();
$li.children().show();
if ($li.hasClass('section')) $li.parent().parent().children().show();
}
// test driver
$(document).ready(function() {
$('li').click(function (e) { open($(this)); e.stopPropagation(); });
});
.content {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="book">
<li class="chapter">Chapter One
<ul class="chapter content">
<li class="section">Section One<br><i class="content">1.1 contents</i></li>
<li class="section">Section Two<br><i class="content">1.2 contents</i></li>
</ul>
</li>
<li class="chapter">Chapter Two
<ul class="chapter content">
<li class="section">Section One<br><i class="content">2.1 contents</i></li>
<li class="section">Section Two<br><i class="content">2.2 contents</i></li>
</ul>
</li>
</ul>
Basically you put the section element you want to be open inside the open($li) function.
You should also only put <li> elements inside <ul> elements.
I hope this is what you wanted.
I want to animate an element (.item-i) after I click on another element(.item-1) which is following below. Now I don't know, how to get to this element.
I want only the exact above element animated, not both above, only the first element above.
I made an easy show up in http://jsfiddle.net/Eef4v/1/. The YellowBG is the "animation".
Here is my JS code:
$('.item-1').click(function() {
$(this).closest('.item-i').css( "background", "yellow" );
});
And my HTML Markup:
<ul id="one" class="level-1">
<li class="item-i">I</li>
<li class="item-ii">II
<ul class="level-2">
<li class="item-a">A</li>
<li class="item-b">B
<ul class="level-3">
<li class="item-1">1</li>
<li class="item-2">2</li>
<li class="item-3">3</li>
</ul>
</li>
<li class="item-c">C</li>
</ul>
</li>
<li class="item-iii">III</li>
</ul>
<ul id="Ul1" class="level-1">
<li class="item-i">I</li>
<li class="item-ii">II
<ul class="level-2">
<li class="item-a">A</li>
<li class="item-b">B
<ul class="level-3">
<li class="item-1">1</li>
<li class="item-2">2</li>
<li class="item-3">3</li>
</ul>
</li>
<li class="item-c">C</li>
</ul>
</li>
<li class="item-iii">III</li>
</ul>
Use:
$(this).closest('.item-ii').prev().css( "background", "yellow" );
Working Demo
For Toggling background color:
$(this).closest('.item-ii').prev().toggleClass("highlight");
CSS:
.highlight {background: yellow;}
Demo with ToggleClass
Two ways to get .item-i to highlight.
$(this).parents('.level-1').find('.item-i').css( "background", "yellow" );
but if you have multiple .item-i classes under your .level-1 then they would all turn yellow.
Working Demo
You could also write a find algorithm that goes through each parent of .item-1 and finds the closest item-i
$('.item-1').click(function () {
$(this).parents().each(function(index,elem){
var query = $(elem).find('.item-i');
if(query.length > 0)
{
query.first().css("background-color", "yellow");
return false;
}
});
});
Working Algorithm demo
how i can get "Goods" when i click under "Goods" link "Restricted","Open" similarly when how i can get "Services" when i click under "Services" link "Restricted","Open" similarly,thanks in advance
JavaScript:
$('.goodsLink li a').click(function(){
alert( $('#nav li ul li a').html());
return false;
});
HTML:
<ul id="nav">
<li>Create a New Tender
<ul>
<li><strong>+</strong> Goods
<ul>
<li><strong>-</strong> Single
<ul class="goodsLink">
<li> - Restricted
</li>
<li> - Open
</li>
</ul>
</li>
<li><strong>-</strong> Framework
<ul class="goodsLink">
<li> - Restricted
</li>
<li> - Open
</li>
</ul>
</li>
</ul>
</li>
<li><strong>+</strong> Services
<ul>
<li><strong>-</strong> Single
<ul class="servicesLink">
<li> - Restricted
</li>
<li> - Open
</li>
</ul>
</li>
<li><strong>-</strong> Framework
<ul class="servicesLink">
<li> - Restricted
</li>
<li> - Open
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
You can use something like this:
$('.goodsLink li a').click(function() {
alert( $(this).parents('li:contains("+")').children("a:first").text());
return false;
});
But the best way should be for you to use a class or tribute to better identify the element you want to find. That way you cold replace the :contains("+") with a .topParent
She this examples:
example with contains
example with class
HTML:
<li class="page_item ">
A
<ul class="children">
<li class="page_item">1</li>
<li class="page_item">2</li>
</ul>
</li>
<li class="page_item ">
B
<ul class="children">
<li class="page_item">1</li>
<li class="page_item">2</li>
<li class="page_item">3</li>
<li class="page_item">4</li>
</ul>
</li>
<li class="page_item ">
C
<ul class="children">
<li class="page_item">1</li>
<li class="page_item">2</li>
<li class="page_item">3</li>
<li class="page_item">4</li>
</ul>
</li>
JS:
$('.page_item').click(function() {
var that = this;
$('.page_item').each(function() {
if (that == this) return true; //continue
$('.children:not(:hidden)', this).slideToggle();
});
$('ul.children', this).slideToggle();
});
Online demo: http://jsfiddle.net/kHLuR/1/
How can I make the first section li opened by default?
Variant #1 Pure CSS solution:
.page_item:first-child .children {
display: block;
}
Demo: http://jsfiddle.net/dfsq/kHLuR/7/
Note: :first-child works in IE8+. If you need to support older version you can give another class to your first li, e.g: <li class="page_item page_item-first"> http://jsfiddle.net/dfsq/kHLuR/9/
Variant #2. Trigger click event on the first .page_item:
$('.page_item').click(function () {
// ...
})
.filter(':first').click();
Demo: http://jsfiddle.net/dfsq/kHLuR/8/
Add this code to simulate a click event when the page is loaded: LIVE DEMO
$(document).ready(function () {
$('a').eq(0).trigger('click');
});
You can use jQuery's .ready() to execute code immediately after the page loads.
Take a look at http://api.jquery.com/ready/