Hide a set number of list objects - javascript

I have multiple list objects with the same structure on a page:
Example:
<div class="mainWrapper">
<div class="listWrapper">
<ul>
<li>Object One</li>
<li>Object Two</li>
<li>Object Three</li>
<li>Object four</li>
<li>Object five</li>
</ul>
</div>
<div class="listWrapper">
<ul>
<li>Object One</li>
<li>Object Two</li>
<li>Object Three</li>
<li>Object four</li>
<li>Object five</li>
</ul>
</div>
</div>
Using jQuery, how can I set it so that for each list, only the first 3 objects are showing in each list and the rest are hidden?

You can use :gt() pseudo selector which select all elements at an index greater than index within the matched set.
$('.listWrapper').find('li:gt(2)').hide();
Demo

Try the :gt() (greater than) selector:
$('.listWrapper ul').find('li:gt(2)').hide();
jsFiddle
It's necessary to query the targeted lis in two passes using an additional find(). Otherwise if there are multiple uls, all lis will be treated as a single collection, and only 3 total list items will be shown. This way we hide() selected items as many times as there are lists.
NOTE: You want your initial query to get down to the list itself.
See :gt() selector documentation.

http://jsfiddle.net/GEbxG/
$('div.listWrapper li').each(function(i, elem) {
if($(elem).index() < 3) return;
$(elem).hide();
});

$('.listWrapper li').show().slice(3).hide();
http://api.jquery.com/slice/
You can remove the .show() if all elements are visible initially.
If you don't already have the jQuery object containing all the li elements and/or don't need access to the full element list, you can avoid selecting them at the first place:
$('.listWrapper ul li:gt(2)').hide();

Related

jQuery iterate nested html list

I have a HTML code of nested list giving me a hard time to read with jQuery!
I'm using
$.get();
to get the html then using
$(data).find(".thelist ul");
To get the list only which looks like
<ul>
<li>Draft Page
<ul>
<li>Batch Version 7</li>
</ul>
</li>
<li>info Control System
<ul>
<li>About info</li>
</ul>
<ul>
<li>Application
<ul>
<li>Functionality
<ul>
<li>
Access
</li>
</ul>
<ul>
<li>Login
</li>
</ul>
<ul>
<li>info Desktop
</li>
</ul>
<ul>
<li>Search
</li>
</ul>
<ul>
<li>info Mobile
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>Support</li>
</ul>
<ul>
<li>Technical Manual
<ul>
<li>Formatting
</li>
</ul>
<ul>
<li>Troubleshooting</li>
</ul>
</li>
</ul>
</li>
</ul>
The actual list is more than 200 item! and it can go up to 7 levels!
What im getting is every item that has children the text is including all of their text!.
I need to get the text and the link of each then append or generate my own list with same level but different html structure
Is this the best approach ?
I have tried iterating using $each()
try this it will give all titles with links.
$(function(){
var links = [];
$( "ul" ).find( "a" ).each(function(k,v){
links.push({ title : $(v).text(), link : $(v).attr('href'), level : $(v).parents('ul').length });
});
console.log(links);
});
Assuming the <ul> you've shown above is the one inside the .thelist block.
I think it'll be easier if you just use $(data).find(".thelist ul li") to get all the list items inside the <ul> element (and subelements).
Or, if you want to go down just one level, you can do $(data).find(".thelist ul>li").
And, you can use the following method to avoid selecting children nodes:
$("#foo")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text();
I got this removing children idea from here.
I hope this helps.

Jquery if hasClass then addClass

I know I can do this, I'm just getting lost in the hierarchy and need a second set of eyes on this.
Here's the structure 'm working with:
<div class="nav-column">
<ul>
<li>Link 01
<div>
<ul>
<li>Sublink 01</li>
<li>Sublink 02</li>
<li>Sublink 03</li>
</ul>
</div>
</li>
<li>Link 02</li>
<li>Link 03</li>
</ul>
<div class="home"><h3>Underlying Div</h3></div>
</div>
I am looking to do the following: when you hover over a .nav-column ul li a that visibility of div.home would turn off. Of course there are going to be multiple .nav-columns so I'm making this dynamic.
The jQuery I have right now is:
if ($('.nav-column li').hasClass('active')){
$(this).parent('.nav-column').sibling('div.home').toggleClass("off");
}
without yielding any class addition to the div.home. I already have a hover function adding and removing the class '.active' to the .nav-column li
EDIT EDIT EDIT
I see that I have made a mistake with my code, and in fact the correct code has the div.home OUTSIDE the div.nav-column
This is the proper heirarchy:
<div class="wrapper">
<div class="nav-column">
<ul>
<li>Link 01
<div>
<ul>
<li>Sublink 01</li>
<li>Sublink 02</li>
<li>Sublink 03</li>
</ul>
</div>
</li>
<li>Link 02</li>
<li>Link 03</li>
</ul>
</div>
<div class="home"><h3>Underlying Div</h3></div>
</div>
Once again... I am very sorry... you can sense my sanity levels dropping
Think this is what you want:
$('.nav-column li').each(function(){
if($(this).hasClass('active')) {
$(this).closest('.nav-column').siblings('div.home').toggleClass("off");
}
});
Fiddle:
http://jsfiddle.net/Jf8mp/
Your mistakes:
.sibling('div.home') is wrong, the correct name of method is .siblings()
if condition doesnt determine who is $(this), you have use a function as .each()
UPDATED:
to make it work on hover over .nav-column ul li a:
$('.nav-column li').on('mouseenter','a',function(){
if($(this).closest('li').hasClass('active')) {
$(this).closest('.nav-column').siblings('div.home').toggleClass("off");
}
});
Fiddle:
http://jsfiddle.net/Jf8mp/2/
You need to use .parents() instead of .parent(). .parents() traverses up multiple levels of the DOM while .parent() retrieves the immediate parent of the element matching the selector.
$(this).parents('.nav-column').siblings('div.home').toggleClass("off");
Since you're not targetting the direct parent (ul) of the element matching the selector, you'll need to use .parents() instead.
In addition, you have a second problem. According to your code structure div.home is not a sibling of .nav-column. You can use .find() for this instead.
Per your last edit, the previous statement is no longer applicable. The code snippets have been updated to reflect your edited change.
Alternatively, you could do the following to accomplish the same effect:
$(this).parents('.nav-column').next().toggleClass("off");
use .closest() or .parents() instead of .parent(). also div home is not sibling of .nav-column. You need to use .find() instead of .siblings().Try this:
$(this).closest('.nav-column').find('div.home').toggleClass("off");
or
$(this).parents('.nav-column').find('div.home').toggleClass("off");
the .parent() only goes up one node, you need to use .parents('select')
If I understand:
$('.nav-column li').forEach(elem, index){
elem = $(elem);
if (elem.hasClass('active')){
elem.addClass("Cheese");
}
}
This would add the class "Cheese" to any active li :)

How to get offset of <li> in nested <ul>

I am having the following HTML
<ul>
<li>List item one</li>
<li>List item two with subitems:
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Final list item</li>
I am trying to find offset() of all 'li' including sub list 'li'. But it always returns same value for all 'li'
script
$('li').offset().left;
Is this correct? How to get the offset for all 'li' ?
You need to loop with each like
$('li').each(function(){
alert($(this).offset().left);
});
use each() to loop through all the li and get the corresponding offset()
$('li').each(function(){
console.log($(this).offset().left);
});
fiddle

How to add LI in UL in arbitrary position using jQuery

I want to add LI in my existing UL. My HTML is like this:
<ul id="friends">
<li>Friend 2</li>
<li>Friend 3</li>
<li>Friend 4</li>
<li>Friend 6</li>
<li>Friend 7</li>
<li>Friend 8</li>
</ul>
i know i can use it to add LI at the and
$("#friends").append('<li>Friend 1</li>');
But it will add in last position and i want to add it at first position or in middle. How to specify the position at which I want to insert the LI?
You have to use prepend() instead of append
$("#friends").prepend('<li>Friend 1</li>');
To append at particular position you can use eq()
$("#friends li").eq(4).append('<li>Friend 1</li>');
Try prepend.
$("#friends").prepend('<li>Friend 1</li>');

How to Insert an incremental variable with Javascript/Jquery?

This, I'm sure is a pretty basic question about JavaScript, so apologies in advance.
I have simple unordered list:
<ul>
<li>Item number 1</li>
<li>Item number 2</li>
<li>Item number 3</li>
<li>Item number 4</li>
<li>Item number 5</li>
</ul>
How would I be able to prepend an incremental number to those 5 items,
so I get:
<ul>
<li><span>1</span>Item number 1</li>
<li><span>2</span>Item number 2</li>
<li><span>3</span>Item number 3</li>
<li><span>4</span>Item number 4</li>
<li><span>5</span>Item number 5</li>
</ul>
The logic behind the increment variable is getting me.
You can iterate over the elements using $.each, using the index argument on the callback function, then build the span element using the current element, and we prepend it to the li:
$('ul li').each(function (i) {
$('<span>'+ (i+1) +'</span>').prependTo(this);
// or $('<span></span>').html(i+1).prependTo(this);
});
Check the above snippet here.
Note that I'm adding one to the index i+1, that's because the indexes are zero-based, also I wrap the addition between parentheses because it is in the middle of a string concatenation.
In steps it'd look like this:
You take all LI items and iterate through all of them by adding span with (lis[index]+1)
Next time you insert a LI element you insert it with span who's text is lis.length+1.

Categories

Resources