Find the place of an element - javascript

I have a list
<ul>
<li class="list_1">a</li>
<li class="list_2">b</li>
<li class="list_3">c</li>
<li class="list_4">d</li>
</ul>
This is in a carousel, so that the list items change position (1-2-3-4, 2-3-4-1, 3-4-1-2, 4-1-2-3,...)
How can I find out, using javascript, which item is in, let's say, second and third position?
In the beginning, the list_2 and list_3 are in second and third position, after one cycle, the list_3 and list_4 are in second and third position, etc.
How to find out what list is in those positions, while I cycle through? For starters I just need to see it displayed in console with console.log(), something like:
On 2nd place is list_3, and on third is list_4.
Tried with this but doesn't work:
var $list_items = $(this).find('ul li');
$list_items.each(function(i,j){
$(this).addClass('list_' + (i+1));
console.log($list_items.eq(2).attr('class'));
});
I'm using $(this) because my original lists are enclosed in a div, and originally lists had no class, so I added them.

One approach is to use map() and index() to create an array of the element's class-name and index, obviously this depends on what, precisely, you want to find; but your question is somewhat vague on the result you want:
function mapIndices() {
// iterate over the 'ul li' elements, forming a map:
return $('ul li').map(function() {
// returning the className (classes) of the element and its index amongst
// siblings:
return this.className + ': ' + $(this).index();
// converting to an Array:
}).get();
};
// this is just a simple trigger to move the elements,
// to demonstrate binding the function:
$('#change').on('click', function() {
var ul = $('ul');
ul.find('li:first-child').appendTo(ul);
console.log(mapIndices());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="change">advance positions</button>
<ul>
<li class="list_1">a</li>
<li class="list_2">b</li>
<li class="list_3">c</li>
<li class="list_4">d</li>
</ul>
If, however, you simply want to find out which element is in a specific position:
$('#change').on('click', function() {
var ul = $('ul');
ul.find('li:first-child').appendTo(ul);
// bear in mind that JavaScript has zero-based indexing,
// 2 is the index of third element, not the second:
console.log(ul.find('li').eq(2));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="change">advance positions</button>
<ul>
<li class="list_1">a</li>
<li class="list_2">b</li>
<li class="list_3">c</li>
<li class="list_4">d</li>
</ul>
References:
eq().
find().
get().
index().
map().
on().

Array manipulation:
var arr = $('li').get(); // http://api.jquery.com/get/
// var arr = ["aa","bb","cc","dd"]; // you can try also using this guy
function doIt(){
if(this.id==="next") arr.push( arr.shift() ); // send first to last
else arr.unshift( arr.pop() ); // send last to first
$('ul').html( arr );
}
$('#prev, #next').on('click', doIt);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="prev">PREV</button>
<button id="next">NEXT</button>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>-----------</li>
</ul>

First give an id/class to the ul:
<ul id="mylist">
<li class="list_1">a</li>
<li class="list_2">b</li>
<li class="list_3">c</li>
<li class="list_4">d</li>
</ul>
Using jQuery to access the 'li' element at 2nd position:
var second_li = $('#mylist').find('li')[1]; // to access 2nd li use index 1
var second_li_class = $(second_li).attr('class'); // second_li_class will be equal to 'list_2'
var second_li_content = $(second_li).html(); // second_li_content will be equal to 'b'

Related

Filter list items after storing in variable

I am trying to store some list item into a variable and then loop through the variable and display only the list items that have a certain data attribute. It is worth mentioning that just using a simple show/hide on the li's on the page will not work for what I'm doing. https://jsfiddle.net/0jbnLv0k/
HTML:
<ul>
<li data-color="blue"></li>
<li data-color="red"></li>
<li data-color="green"></li>
<li data-color="blue"></li>
<li data-color="red"></li>
<li data-color="green"></li>
</ul>
<button class="blue">blue</button>
<button class="red">red</button>
<button class="yellow">yellow</button>
Jquery:
var items = $('ul li');
items.remove();
var result = $.grep(items, function(e){ return e.data == 'blue'; });
$('ul').html('<li>' + result + '</li>');
Problem is that
typeof e.data === 'undefined'
Solution is this:
var items = $('ul li');
items.remove();
var result = $.grep(items, function(e){
return $(e).attr('data-color') == 'blue';
});
$('ul').append( result );
But this is very bad end expensive ( time consuming ) way to display DOM elements. Much better would be add class with
display: none;
property.
Instead all this code you can use only one line:
$("li:not([data-color='blue'])").addClass('hide')
$("button").click(function() {
var getClass = $(this).attr("class");
$("ul").find("li").not("li[data-color="+getClass+"]").remove();
});
you could use not selector removing all list elements except the selected class.
https://jsfiddle.net/0jbnLv0k/5/

target a <li> so that you can click

I am currently developing a program. It includes a 3 option navigation bar. It uses <li> and does not have id's, when i try to add id's to them it messes up the order, and doesent even work with a click! Im starting to loose faith with it.. can anyone help me on this one,
my GOAL is to have it alert different things on different clicks, so than I could link different html pages,
fiddle used HERE.
<ul class="ui-module menu-selector" id="menu-selector">
<li>Home</li>
<li class="js-is-active">Notif's</li>
<li>Profile</li>
</ul>
Since you don't have ids, I suppose that childNodes property will help a lot.
For example, you can use:
var lis = document.getElementById('menu-selector').childNodes;
// or you can select lis directly...
// var lis = document.querySelectorAll('#menu-selector li');
Array.prototype.slice.call(lis)
.forEach(function(li) {
// do something... like
li.onclick = function () {
console.log(this);
}
});
Note: childNodes (or querySelectorAll return) is NodeList type, and I use Array.prototype.slice.call() in order to use forEach() method on it.
See childNodes for more details.
if you don't want to have ids on your li elements for some reason you can use the following logic to select active li:
$("#menu-selector li.active").on("click", function(){
alert($(this).text())
});
I added id's for you, not sure what you meant by it messing up the order.
HTML
<div class="ui-items">
<header class="ui-module app-header">VoiceBox <i class="entypo-user-add"></i>
<i class="entypo-pencil"></i>
</header>
<div id="outer">
<ul class="ui-module menu-selector" id="menu-selector">
<li id="home_li">Home</li>
<li id="notif_li" class="js-is-active">Notif's</li>
<li id="profile_li">Profile</li>
</ul>
</div>
</div>
Javascript
var listItem = $('#menu-selector > li');
$(listItem).click(function() {
$(listItem).removeClass('js-is-active');
$(this).toggleClass('js-is-active');
});
$('#home_li').click(function(){
alert('home clicked')
})
$('#notif_li').click(function(){
alert('notifs clicked')
})
$('#profile_li').click(function(){
alert('profile clicked')
})
Fiddle http://jsfiddle.net/1swep9oq/2/

Sort and separate a set of list elements using JavaScript/jQuery

I have a question
Sort the list (you can use default JS/jquery sorting functions )
Break the sorted list apart into different sub-lists with a maximum of 'x' items each, 'x' being a parameter you pass in. The above
sample result assumes x=2
<ul>
<li> 4 </li>
<li> 1 </li>
<li> 7 </li>
<li> 5 </li>
<li> 3 </li>
</ul>
Write a function to convert that to
<ul>
<li> 1 </li>
<li> 3 </li>
</ul>
<ul>
<li> 4 </li>
<li> 5 </li>
</ul>
<ul>
<li> 7 </li>
</ul>
Feel free to use any libraries/references you like within reason (i.e., don't use a library which has a "splitList" function). The key is to do this as efficiently as possible in terms of DOM manipulation.
i solved this question by creating separate list and deleted the original but I am wondering how can we do it by only modifying the existing one.(I mean modify on the fly while traversing)
html first:
<ul id="list">
<li> 4 </li>
<li> 1 </li>
<li> 7 </li>
<li> 5 </li>
<li> 3 </li>
</ul>
<div id="container"></div>
javascript(jquery):
function sortText(a,b){
return $(a).text().trim() > $(b).text().trim() ? 1 : -1;
};
var ul = $('#list');
var elements = ul.find('li').detach();
var i=2;
var lastul;
var container = $('#container');
elements.sort(sortText).each(function(index){
if (index % i === 0) {
container.append(lastul);
lastul = $('<ul></ul>');
}
lastul.append(elements[index]);
})
container.append(lastul);
ul.remove();
var optionTexts = [];
$("ul li").each(function() { optionTexts.push($(this).text()) });
optionTexts.sort();
//alert(optionTexts.length);
var splityby = 2;//change this value how you want to split
var itmes= parseInt(optionTexts.length/splityby);
var remaining = optionTexts.length%splityby;
//alert(itmes+'and'+remaining);
var st='';
var i=0;
for(k=0;k<itmes+remaining;k++){
st+='<ul>';
for(j=0;j<splityby;j++){
if(i<optionTexts.length){
st+='<li>'+optionTexts[i++] +'</li>' ;
}
}
st+='</ul>';
}
$('#hi').append(st);
html
<div id="hi"></div>
<ul> <li> 4 </li> <li> 1 </li> <li> 7 </li> <li> 5 </li> <li> 3 </li> </ul>
The most efficient method to sort is by using the native Array.sort method (jQuery().sort implements the Array.sort). Fiddle: http://jsfiddle.net/RJEJQ/1/.
The code can become even more efficient by getting rid of jQuery, and using document.createElement() and ordinary for() loops.
var originalUl = $('ul');
var listElements = originalUl.children('li'); //List
listElements.sort(function(x, y){
return parseInt(x.textContent, 10) - parseInt(y.textContent);
});
//Sorted by number, 1, 2, 3, ...
var newList = $(""); //Placeholder
listElements.each(function(i){
if(i%2 == 0){ //If even, a new list has to be created
originalUl.before(newList);
newList = $("<ul>"); //Create new list
}
newList.append(this);
});
if(newList.length) { // If there are any remaining list elements in the holder.
originalUl.before(newList);
}
originalUl.remove(); //Remove original, empty ul.
As seen at this demo, the result looks like:
ul
li 1
li 3
ul
li 4
li 5
ul
li 7
This partially uses an answer I wrote before that divides elements into groups, with the addition of sorting them first:
Working demo: http://jsfiddle.net/AndyE/QVRRn/
var i = 0,
ul = $("ul"),
lis = ul.children().detach(),
group;
// Sort the elements
lis.sort(function (a, b) {
return $.text(a).localeCompare($.text(b));
});
// Wrap the elements
while ((group = lis.slice(i, i += 2)).length)
group.wrapAll('<ul></ul>');
// Replace the original UL element
ul.replaceWith(lis.closest("ul"));
It's important to detach the <li> elements from the document before manipulating them, this will make the operation much faster on large sets.
If you must have to manipulate DOM, I believe your question was answered.
But...
DOM manipulation is slow.
Concatenate strings also.
The sort function was taken from here: How may I sort a list alphabetically using jQuery?
Live demo:
http://jsfiddle.net/gknjQ/1/

jQuery UI get the sorted position of LI element in UL

I'm using jQuery UI's sortable for my UL list. Each time the user sorts the list, I want each li element to update it's "position" attribute to it's position in the list.
<ul>
<li position="1">a</li>
<li position="2">b</li>
<li position="3">c</li>
</ul>
So when a user swaps c with a, the position will also update. I tried to use .each but it seems that javascript doesn't follow the order of how the LI elements are displayed but the order of the element's creation.
As mentioned in another answer, using update is all you need:
$(function() {
var $sortable = $('ul').sortable({
update: function(event, ui) {
var counter = 1;
$('li', $sortable).each(function() {
$(this).attr('position', counter);
counter++;
});
}
});
});
Example link
Have you tried :eq selector or index method? Provided you know which li element you're trying to find the position of you could find the position like so:
<ul>
<li id="c">c</li>
<li id="b">b</li>
<li id="a">a</li>
</ul>
var position = $('li#b').index();
You'll want to take advantage of the Sortable "update" event:
$( "ul" ).sortable({
update: function(event, ui) {
var order = $(this).sortable('serialize');
console.info(order);
}
});
You can then use the "serialize" method to pull the updated order of items. One requirement for this to work is that the IDs of each list item contain an underscore, so you'd want to update your HTML to:
<ul>
<li id="position_1">a</li>
<li id="position_2">b</li>
<li id="position_3">c</li>
</ul>

Get all LI elements in array

How can i make JS select every LI element inside a UL tag and put them into an array?
<div id="navbar">
<ul>
<li id="navbar-One">One</li>
<li id="navbar-Two">Two</li>
<li id="navbar-Three">Three</li>
<li id="navbar-Four">Four</li>
<li id="navbar-Five">Five</li>
</ul>
</div>
Can i make it so JS gets each of them into an array eg
navbar['0'] would return document.getElementById("navbar-One")?
You can get a NodeList to iterate through by using getElementsByTagName(), like this:
var lis = document.getElementById("navbar").getElementsByTagName("li");
You can test it out here. This is a NodeList not an array, but it does have a .length and you can iterate over it like an array.
After some years have passed, you can do that now with ES6 Array.from (or spread syntax):
const navbar = Array.from(document.querySelectorAll('#navbar>ul>li'));
console.log('Get first: ', navbar[0].textContent);
// If you need to iterate once over all these nodes, you can use the callback function:
console.log('Iterate with Array.from callback argument:');
Array.from(document.querySelectorAll('#navbar>ul>li'),li => console.log(li.textContent))
// ... or a for...of loop:
console.log('Iterate with for...of:');
for (const li of document.querySelectorAll('#navbar>ul>li')) {
console.log(li.textContent);
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
<div id="navbar">
<ul>
<li id="navbar-One">One</li>
<li id="navbar-Two">Two</li>
<li id="navbar-Three">Three</li>
</ul>
</div>
QuerySelectorAll will get all the matching elements with defined selector. Here on the example I've used element's name(li tag) to get all of the li present inside the div with navbar element.
let navbar = document
.getElementById("navbar")
.querySelectorAll('li');
navbar.forEach((item, index) => {
console.log({ index, item })
});
<div id="navbar">
<ul>
<li id="navbar-One">One</li>
<li id="navbar-Two">Two</li>
<li id="navbar-Three">Three</li>
<li id="navbar-Four">Four</li>
<li id="navbar-Five">Five</li>
</ul>
</div>
If you want all the li tags in an array even when they are in different ul tags then you can simply do
var lis = document.getElementByTagName('li');
and if you want to get particular div tag li's then:
var lis = document.getElementById('divID').getElementByTagName('li');
else if you want to search a ul first and then its li tags then you can do:
var uls = document.getElementsByTagName('ul');
for(var i=0;i<uls.length;i++){
var lis=uls[i].getElementsByTagName('li');
for(var j=0;j<lis.length;j++){
console.log(lis[j].innerHTML);
}
}
var allElmnts = document.querySelectorAll("ul");
var arr = [];
arr.length = allElmnts.length;
for(var i = 0; i < allElmnts.length; i++){
arr[i] = allElmnts[i];
}

Categories