How to match list items with values in an array - javascript

I have an array, it contains values [1,2].
I also have an html list
<ul>
<li id="1">List Item 1</li>
<li id="2">List Item 2</li>
<li id="3">List Item 3</li>
</ul>
I need to iterate through the array, and if a value in the array matches an ID in my list, add a class to the list item.
The output example would be
<ul>
<li id="1" class="active">List Item 1</li>
<li id="2" class="active">List Item 2</li>
<li id="3">List Item 3</li>
</ul>
I'm a bit lost on this one, thanks in advance!

Try to use $.map() to translate the array into "#1,#2" and pass it as a selector then add class to it,
var arr = [1,2]; // var arr = Express.completedSteps;
$($.map(arr,function(val,_){
return "#" + val;
}).join()).addClass('active');
DEMO

try
var arr=[1,2];
for(var i in arr){
$("#"+arr[i]).addClass("active");
}
DEMO

Try out following.
$(document).ready(function(){
var obj = [1,2,5,7];
$.each( obj, function( key, value )
{
$('li').each(function(){
if($(this).attr('id')==value)
{
$('#'+value).addClass( "active" );
}
});
});
})
try out the demo here.
demo

Related

Get index of an element from a NodeList

I have a simple list:
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
And need to get index of a specific item disregarding hidden items.
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
I try to convert NodeList in Array:
var list_items = Array.from(items);
But don't known how to run something like that: list_items.indexOf('item-3')
https://codepen.io/marcelo-villela-gusm-o/pen/RwNEVVB?editors=1010
You can make a function to find the id you need in a list you want, passing two parameters, that way you can use this function dynamically.
Based on id, inside the function just need to use .findIndex() that returns the index or -1 if not found.
See here:
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
var list_items = Array.from(items);
function getIndexById(idToSearch, list){
//ES6 arrow function syntax
return list.findIndex(elem => elem.id == idToSearch)
//normal syntax
//return list.findIndex(function(elem) {return elem.id == idToSearch})
}
console.log("found at index: ", getIndexById("item-3", list_items))
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Not exactly related to the question, but if possible, I would suggest you to change your HTML to remove that inline style of display: none and change it to a class, (e.g: class='hidden'), it would be better for your .querySelector when using :not, for example: li:not(.hidden), since any space in your inline style can break your selector. ("display:none" != "display: none", spot the space)
Maybe like this:
var item = list_items.find(function(item) {
return item.id === "item-3";
});
I would recommend using :not(.hidden) instead of "grepping" for a match on the style tag. Then, simply find the index after casting the NodeList to an array.
For the Vue.js inclined, see this fiddle: https://jsfiddle.net/634ojdq0/
let items = [...document.querySelectorAll('#list li:not(.hidden)')]
let index = items.findIndex(item => item.id == 'item-4')
console.log('item-4 index in visible list is', index)
.hidden {
display: none;
}
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" class="hidden">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Maybe you can use map. First you can create an object with id and value. Then use map function to create array of this object. Then you can access it with foreach, when id = 'item-3'.

JQuery find all elements with a class add their id to a coma separated list

As the title says I want to find all li tags inside an ordered list called #selectable with the class .ui-selected and add their id's to a string with each id separated by a comma.
Here's an example of what my html looks like:
<ol id="selectable">
<li id="1" class="ui-selected"><li>
<li id="2"><li>
<li id="3" class="ui-selected"><li>
<li id="4"><li>
<li id="5" class="ui-selected"><li>
</ol>
Try this:
var selectedIds = $('#selectable .ui-selected').map(function() {
return this.id;
}).get().join(',');
Example fiddle
Was working with my fiddle and couldn't figure out why my test array was returning 10 items in stead of 5. You are not closing your list items use <li></li> in stead of <li><li>.
Your source was missing a /.
I pushed them in an array and converted the array to a string with toString()
var listItems = [];
$('#selectable .ui-selected').each(function(){
var theID = $(this).attr('id');
listItems.push(theID);
});
listItems = listItems.toString();
console.log(listItems);
http://jsfiddle.net/h6G8H/4/

Jquery Mobile Duplicating Autodividers

I have a list but when I try to generate autodividers for that list I'm getting duplicate dividers. Here is the code for the ul and the relevant script:
<div data-role="content">
<ul data-role="listview" id="ScheduleList" data-autodividers="true">
<li time="3:30PM">Event 1</li>
<li time="3:30PM">Event 2</li>
<li time="4:30PM">Event 3</li>
<li time="3:30PM">Event 4</li>
<li time="3:30PM">Event 5</li>
<li time="4:30PM">Event 6</li>
</ul>
</div>
</div>
<script>
$(document).on("pageinit", "#ScheduleDay", function(){
$("#ScheduleList").listview({
autodividers: true,
autodividersSelector: function (li) {
var out = li.attr('time');
return out;
}
}).listview('refresh');
});
</script>
Here is the code in JSFiddle: http://jsfiddle.net/4fGT6/65/
I know that I could reorder the list items in the html and that would eliminate the duplicate autodividers, but if I made the list to be generated dynamically from user inputs then I couldn't manually reorder the html.
Is there a way to solve this if the list had been generated dynamically?
Thanks.
First step, sort list items based on data-time attribute (I added data to facilitate reading values - data attribute is ignored by user agent, thus it won't mess up your code).
I used the below simple code, yet genius, made by #undefined.
Update:
Thanks to #Keir Lavelle for reviewing the code of sorting li elements.
var listview = $('#ScheduleList'),
listitems = listview.children('li');
listitems.detach().sort(function (a, b) {
var adata = $(a).data('time');
var bdata = $(b).data('time');
/* return (adata > bdata) ? (adata > bdata) ? 1 : 0 : -1; */
return (adata > bdata) ? 1 : -1;
});
listview.append(listitems);
Second step, apply autodividers dynamically.
$("#ScheduleList").listview({
autodividers: true,
autodividersSelector: function (li) {
var out = li.jqmData('time');
return out;
}
}).listview('refresh');
Demo
Credits to #undefined and #Keir Lavelle

Identify unique data attributes

I am creating a jquery plugin that will sort a list based on data attributes:
<ul class="reorder">
<li data-rating="1" data-category="3">Rating 1 - Category 3</li>
<li data-rating="5" data-category="1">Rating 5 - Category 1</li>
<li data-rating="2" data-category="2">Rating 2 - Category 2</li>
<li data-rating="7" data-category="1">Rating 7 - Category 1</li>
<li data-rating="21" data-category="3">Rating 21 - Category 3</li>
<li data-rating="19" data-category="2">Rating 19 - Category 2</li>
</ul>
As I don't know how many data attributes will be added, I want to be able to loop through the list and identify unique data attributes (NOT the value of those attributes) to create a set of links:
<ul class="reorder-nav">
<li>Sort by rating</li>
<li>Sort by category</li>
</ul>
My basic idea is to loop through each list item and create an array of data attributes, then filter that array for unique attributes.
I can create an array of all data attributes with .data() but other than that I'm a bit stuck so would appreciate any suggestions.
You can do something like this to extract the data-x attribute names :
var uniqueAttrs = {};
$('.reorder li').each(function(){
$.each(this.attributes, function(_,a){
if (a.name.indexOf('data-')===0) {
uniqueAttrs[a.name.slice(5)] = 1;
}
});
});
Then you can iterate over the keys of uniqueAttrs :
for (var attr in uniqueAttrs) {
console.log(attr); // for example "sort" or "ranking"
}
If you can afford to support a limited set of browsers, you can simplify the loop by using dataset instead of attributes.

set order to jquery sortable

I use jquery draggble function for unorderd list (ul) and face a problem of getting the order of items after it changed and setting the order ofter page is loaded.Suppose we have the following code :
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js> </script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script>
$(document).ready(function(){
$('.secondblock').sortable({axis:'y'});
$(".block").sortable({
axis: 'y',
update: function(event, ui) {// order changed
var order = jQuery(this).sortable('toArray');
// set this order to .secondblock
}
});
});
</script>
</head>
<body>
<ul class="block" type="none">
<li id = "one">1</li>
<li id = "two">2</li>
<li id = "three">3</li>
<li id = "four">4</li>
<li id = "five">5</li>
</ul>
<ul class="secondblock" type="none">
<li id = "one">1</li>
<li id = "two">2</li>
<li id = "three">3</li>
<li id = "four">4</li>
<li id = "five">5</li>
</ul>
</body>
Are there any possible solutions?
First, you shouldn't have the same id appear twice in a document. That will cause all kinds of problems.
Instead, set a data-attribute on the items in the second list to reflect corresponding items in the first list:
<ul class="block" type="none">
<li id = "one">1</li>
<li id = "two">2</li>
<li id = "three">3</li>
<li id = "four">4</li>
<li id = "five">5</li>
</ul>
<ul class="secondblock" type="none">
<li data-block-id = "one">1</li>
<li data-block-id = "two">2</li>
<li data-block-id = "three">3</li>
<li data-block-id = "four">4</li>
<li data-block-id = "five">5</li>
</ul>
Then reflecting the sort of the first list in the second list is simple:
$('.block').sortable({update: sortOtherList});
function sortOtherList(){
$('.block li').each(function(){
$('.secondblock [data-block-id=' + $(this).attr('id') + ']')
.remove()
.appendTo($('.secondblock'));
});
}
See it working here: http://jsfiddle.net/6HKZG/2/
Faust's looks better to me. Mark it if it's what you wanted.
Yes. I feel like I need more information, but I had to do almost the exact same thing recently.
First, you want to extend the javascript array object with a sorting algorithm. Here is what I use:
Array.prototype.move = function (old_index, new_index) {
if (new_index >= this.length) {
var k = new_index - this.length;
while ((k--) + 1) {
this.push(undefined);
}
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
source Move an array element from one array position to another
Then, what I would do is use this along with an OldPosition/NewPosition function to get the index of the element before and after the sort, and use this method to move the object in the array.
I think JQuery sort let's you get information about the array before and after the sort
ex:
$('li').presort(function() {
window.oldindex = $(this).index();
});
$('li').postsort(function() {
window.newindex = $(this).index();
array.move(oldindex,newindex);
});
If you're just looking to make .secondblock match .block after sort, you can do this:
source: http://jqueryui.com/demos/sortable/#events
$( ".selector" ).sortable({
start: function(event, ui) { //Get the order of the .block list items before dragging }
});
$( ".selector" ).sortable({
stop: function(event, ui) { //Get the new order of the list items after dragging. Compare the two orders and sort .secondblock to match block }
});

Categories

Resources