Trying to figure out a way to remove classes in sets of 4 within a list item.
So let's say I have an unorder list with 50 list items with 40 of the items having a class of 'hide'. I have a button that handles a click event to remove 4 of the li's hide class.
HTML
<ul>
<li>foo</li>
<li>foo</li>
<li>foo</li>
<li>foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
<li class="hide">foo</li>
</ul>
<button>Click me to see the next 4 items</button>
JavaScript
$('button').click(function () {
$('li.hide').removeClass('hide');
})
Try like this
$('button').on('click',function() {
$('li.hide').each(function(i) {
if (i == 4)
return false;
$(this).removeClass('hide');
});
});
use the :lt() selector:
$('button').click(function() {
$('li.hide:lt(4)').removeClass('hide');
});
Fiddle: http://jsfiddle.net/mrub5b0z/
Related
<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 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();
});
I try to get an accordion like functionality, I have only <li>with classes .level1, .level2, .level3 ..etc, the issue I have is , if I click on .level2, items will hide until next .level2 element without issues.
But if I click on .level3 and hide .level4, and then click .level2 to hide .level3, I can see .level4 item under .level2.
I don't know how to fix that
Please check demo:
$('.level2').click(function(e) {
if ($(this).next('li').hasClass('level3')) {
$(this).nextUntil('.level2').toggle();
e.preventDefault()
}
})
$('.level3').click(function(e) {
if ($(this).next('li').hasClass('level4')) {
$(this).nextUntil('.level3').toggle();
e.preventDefault()
}
})
$('.level4').click(function(e) {
if ($(this).next('li').hasClass('level5')) {
$(this).nextUntil('.level4').toggle();
e.preventDefault()
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="level1"><span>Level1</li>
<li class="level2"><span>Level2</li>
<li class="level2"><span>Level2</li>
<li class="level3"><span>Level3</li>
<li class="level3"><span>Level3</li>
<li class="level3"><span>Level3</li>
<li class="level4"><span>Level4</li>
<li class="level2"><span>Level2</li>
<li class="level3"><span>Level3</li>
<li class="level4"><span>Level4</li>
<li class="level4"><span>Level4</li>
<li class="level3"><span>Level3</li>
<li class="level4"><span>Level4</li>
<li class="level2"><span>Level2</li>
<li class="level3"><span>Level3</li>
<li class="level4"><span>Level4</li>
<li class="level4"><span>Level4</li>
<li class="level2"><span>Level3</li>
</ul>
Not sure what you are trying to achieve, Have a look on this, it might give you ideas of doing it cleaner and more efficient:
$('li a').click(function (e){
if($(this).parent().find('>ul').length>0){
$(this).parent().find('>ul').toggle();
}
e.preventDefault();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><span>Level1
<ul>
<li><span>Level2
<ul>
<li><span>Level3</li>
<li><span>Level3</li>
<li><span>Level3</li>
<li><span>Level3</li>
</ul>
</li>
<li><span>Level2</li>
<li><span>Level2</li>
<li><span>Level2
<ul>
<li><span>Level3</li>
<li><span>Level3</li>
<li><span>Level3</li>
<li><span>Level3</li>
</ul>
</li>
</ul>
</li>
</ul>
You're probably going about this in the wrong way if you're looking to toggle a structured menu of nested lists. But assuming you DO want to have an arbitrary flat list, you need to check if the following item is visible and then explicitly call show() or hide(). For example:
$('.level2').click(function (e){
toggleUntil(this, 'level3', 'level2');
e.preventDefault();
})
$('.level3').click(function (e){
toggleUntil(this, 'level4', 'level3');
e.preventDefault();
});
$('.level4').click(function (e){
toggleUntil(this, 'level5', 'level4');
e.preventDefault();
})
function toggleUntil(x, start, last) {
if ($(x).next('li').hasClass(start)) {
if ($(x).next('li').is(':visible')) {
$(x).nextUntil('.' + last).hide();
} else {
$(x).nextUntil('.' + last).show();
}
}
}
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
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/