Target multiple lists in jquery - javascript

I have three lists with the same class names. On load, I only show 5 list items per list and there are "show more" buttons which reveals the rest of the list items when clicked.
I want the behaviour such that, when the 'show more" button is pressed for one list, it also shows the hidden list items for the other lists.
My predicament is that the 3 lists behave like 1 big list and show the list items sequentially, instead of showing all the items for all lists together.
Any idea how I can get all the lists to behave in unison?
$(document).ready(function(){
var list = $(".list li");
var numToShow = 5;
var button = $(".next");
var numInList = list.length;
list.hide();
if (numInList > numToShow) {
button.show();
}
list.slice(0, numToShow).show();
button.click(function(){
var showing = list.filter(':visible').length;
list.slice(showing - 1, showing + numToShow).fadeIn();
var nowShowing = list.filter(':visible').length;
if (nowShowing >= numInList) {
button.hide();
}
});
});
.list {
padding: 0;
margin: 0;
}
.list li {
position: relative;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<h1> LIst 1</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="next">Show More</button>
<h1> LIst 2</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="next">Show More</button>
<h1> LIst 3</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="next">Show More</button>
</div>

You must treat the lists separately, like this:
$(document).ready(function(){
var $list = $(".list");
var numToShow = 5;
var $buttons = $(".next");
$buttons.hide();
$list.each(function() {
var $listItems = $(this).find("li");
var $button = $(this).next('.next');
var numInList = $listItems.length;
$listItems.hide();
if (numInList > numToShow) {
$button.show();
}
$listItems.slice(0, numToShow).show();
})
$buttons.click(function(){
var $this = $(this);
var $list = $this.prev(".list");
var $listItems = $list.find("li");
var showing = $listItems.filter(':visible').length;
$listItems.slice(showing - 1, showing + numToShow).fadeIn();
var nowShowing = $listItems.filter(':visible').length;
var numInList = $listItems.length;
if (nowShowing >= numInList) {
$this.hide();
}
});
});
.list {
padding: 0;
margin: 0;
}
.list li {
position: relative;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<h1> LIst 1</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="next">Show More</button>
<h1> LIst 2</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="next">Show More</button>
<h1> LIst 3</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="next">Show More</button>
</div>

As already mentioned by Pedro, the problem with your code is that you select all the li elements at once, no matter which list they belong to.
You should iterate through lists and work with their items separetely.
And if you want behaviour such that, when the 'show more' button is pressed for one list, it also shows the hidden list items for the other lists, you need to iterate through lists on each button click too and show a needed number of items for each of lists.
$(document).ready(function(){
var numToShow = 3;
$(".list").each(function(i, list) {
var li = $(list).find("li");
var numInList = li.length;
li.hide();
if (numInList > numToShow) {
$(list).next(".next").show();
}
li.slice(0, numToShow).show();
});
$(".next").click(function() {
$(".list").each(function(i, list) {
var li = $(list).find("li");
var numInList = li.length;
var showing = li.filter(':visible').length;
li.slice(showing - 1, showing + numToShow).fadeIn();
var nowShowing = li.filter(':visible').length;
if (nowShowing >= numInList) {
$(list).next(".next").hide();
}
});
});
});
.list {
padding: 0;
margin: 0;
}
.list li {
position: relative;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<h1> List 1</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
<button class="next">Show More</button>
<h1> List 2</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
<button class="next">Show More</button>
<h1> List 3</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
</ul>
<button class="next">Show More</button>
</div>

Related

Revert list to previous order after prependTo using Jquery

I have a list which shows only four (featured) list items initially, and once a 'show more' button is clicked, it reveals the remainder of the list. I use$('.featured').prependTo('.feature-list'); to display the featured items first. However, when I click the 'show more' button, I want the list to be displayed in the original order before the prependTo happened. I can't seem to figure out how to do this.
$('.featured').prependTo('.feature-list');
$('.feature-list').find('li:gt(3)').hide();
$('.more-btn').click(function() {
$('.feature-list li:gt(3)').show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>List 1</p>
<ul class="feature-list feature-p-list1">
<li>Item 1</li>
<li class="featured">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li class="featured">Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li class="featured">Item 8</li>
<li class="featured">Item 9</li>
<li>Item 10</li>
</ul>
<button class="more-btn">Show More</button>
Just try hide and show using :not() filter
https://api.jquery.com/not-selector/
$('.feature-list > li:not(.featured)').hide()
$('.more-btn').click(function() {
$('.feature-list > li:not(.featured)').show()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>List 1</p>
<ul class="feature-list feature-p-list1">
<li>Item 1</li>
<li class="featured"><b>Item 2</b></li>
<li>Item 3</li>
<li>Item 4</li>
<li class="featured">Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li class="featured">Item 8</li>
<li class="featured">Item 9</li>
<li>Item 10</li>
</ul>
<button class="more-btn">Show More</button>

Hide items from two or more lists with the same class name

I've got two lists with the same class name which show only the first 4 items. When either of the 'more' button below them is clicked, I wish to reveal the rest of the items for both lists. This behaviour works fine. Only problem is that the following line: $('.feature-list li:gt(3)').hide(); shows the first 4 items for only the first list and not the second. Any way I can target both lists?
$('.feature-list li:gt(3)').hide();
$('.more-btn').click(function() {
$('.feature-list li:gt(3)').show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>List 1</p>
<ul class="feature-list feature-p-list1">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="more-btn">Show More</button>
<p>List 2</p>
<ul class="feature-list feature-p-list2">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="more-btn">Show More</button>
You can use find method to find li under each list. Otherwise, it will all consider as a single array.
Bonus:
Fixed the problem on clicking the Show more button for individual lists. Cheer!
$('.feature-list').find('li:gt(3)').hide()
$('.more-btn').click(function() {
$(this).parent().find('.feature-list li:gt(3)').show();
//$('.feature-list li:gt(3)').show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<p>List 1</p>
<ul class="feature-list feature-p-list1">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="more-btn">Show More</button>
</section>
<section>
<p>List 2</p>
<ul class="feature-list feature-p-list2">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
<button class="more-btn">Show More</button>
</section>

jQuery Each, Iterate from starting element? [duplicate]

This question already has answers here:
jQuery: How to use each starting at an index other than 0
(3 answers)
Closed 7 years ago.
Is it possible to start an each loop starting from a certain element instead of all the elements?
e.g. If i wanted to make items above "Item two" red. (I'm aware there's no need for an each loop to do that, this is just an example case)
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
$('li').each(function(){
$(this).css("color", "red");
});
You can check current item index and skip iteration:
$('li').each(function(){
if( $( this ).index() < 2 ) return true;
$(this).css("color", "red");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
You can use index property of .each function.
$('li').each(function(index) {
if (index > 1) {
$(this).css("color", "red");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
This can be done as follows
$(document).ready(function(){
var lis = $('ul').children();
console.log($(lis).length);
for(var i = 1; i < 3; i++)
{
$(lis[i]).css("color", "red");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>

Sort unordered list with Javascript / jQuery

I am creating unordered lists dynamically. This creates an output similar to this:
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<ul>
<li>Item 3.1</li>
<li>Item 3.2</li>
<li>Item 3.3</li>
</ul>
<li>item 4</li>
<li>Item 5</li>
<ul>
<li>Item 5.1</li>
<li>Item 5.2</li>
<li>Item 5.3</li>
</ul>
<li>item 6</li>
</ul>
I would like to be able to sort through them, after they are created, so that any item that has a sublist(for example item 3 & item 5) will go to the top of the list, for output like this:
<ul>
<li>item 3</li>
<ul>
<li>Item 3.1</li>
<li>Item 3.2</li>
<li>Item 3.3</li>
</ul>
<li>Item 5</li>
<ul>
<li>Item 5.1</li>
<li>Item 5.2</li>
<li>Item 5.3</li>
</ul>
<li>item 1</li>
<li>item 2</li>
<li>item 4</li>
<li>item 6</li>
</ul>
I am thinking I can do this with jQuery or the javascript .sort() method but I'm not sure where to go with it. Any advice?
Firstly you should put your sublists inside their parent element and give a class to your list, like this:
<ul class="autoReorder">
<li>item 1</li>
<li>item 2</li>
<li>item 3
<ul>
<li>Item 3.1</li>
<li>Item 3.2</li>
<li>Item 3.3</li>
</ul>
</li>
<li>item 4</li>
<li>Item 5
<ul>
<li>Item 5.1</li>
<li>Item 5.2</li>
<li>Item 5.3</li>
</ul>
</li>
<li>item 6</li>
</ul>
Then in jQuery here is your solution:
$(document).ready(function(){
$('ul.autoReorder').find('li ul').parent().prependTo('ul.autoReorder');
});

How to append li inside new div

I have a HTML markup like this:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
How can I convert above HTML into this:
<div class="main"><ul><li>Item 1</li><li>Item 2</li></ul></div>
<div class="main"><ul><li>Item 3</li><li>Item 4</li></ul></div>
<div class="main"><ul><li>Item 5</li><li>Item 6</li></ul></div>
<div class="main"><ul><li>Item 7</li><li>Item 8</li></ul></div>
You can do like this:
$('ul > li:nth-child(2n-1)').each(function() {
$(this).next().add(this).wrapAll('<div class="main"><ul></ul></div>');
}).eq(0).closest('div').unwrap();
Working Demo

Categories