How to get the maximum value from the HTML attributes - javascript

My HTML looks like:
<ul>
<li data-target="12">1</li>
<li data-target="4">2</li>
<li data-target="9">3</li>
<li data-target="15">4</li>
<li data-target="23">5</li>
<li data-target="32">6</li>
<li data-target="7">7</li>
<li data-target="10">8</li>
<li data-target="5">9</li>
<li data-target="2">10</li>
</ul>
What method should I use to get the maximum value from the data-target attributes? Do vanilla JavaScript or jQuery have some native functions for this or I should just use for loop to iterate through all the items and get the maximum value, shouldn't I?

One way (without bothering with an array);
var max = 0;
$("li[data-target]").each(function() {
max = Math.max(max, parseInt($(this).data("target"), 10));
});
alert(max);

use Math.max.apply() method to get max value from a numeric array.
var arr = $('li[data-target]').map(function(){
return $(this).data('target')
});
console.log(Math.max.apply(Math,arr));
Fiddle Demo

Try this: use .map() along with Math function:
var targets = $("li").map(function() {
return $(this).data("target");
}).get();
var max = Math.max.apply(Math,targets);
Demo

This should work...
var array = [];
$('li').each(function() {
array.push($(this).data('target'));
});
var maxNumber = Math.max.apply(Math, array);
alert(maxNumber);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li data-target="12">1</li>
<li data-target="4">2</li>
<li data-target="9">3</li>
<li data-target="15">4</li>
<li data-target="23">5</li>
<li data-target="32">6</li>
<li data-target="7">7</li>
<li data-target="10">8</li>
<li data-target="5">9</li>
<li data-target="2">10</li>

var maxVal = 0;
$('[data-target]').each(
function(){
if($(this).attr('data-target') > maxVal){
maxVal = $(this).attr('data-target');
}
});
fiddle

Try with this:
var maxValue = 0;
$("li").each(function(index,val){
var value = $(this).attr('data-target');
if(value > maxValue) maxValue= value;
});

Yes you can get max value using for each loop of jquery. For each value of li get its attribute data-target. e.g
var maxVal=0;
$(this).find('li').each(function(){
// cache jquery var
var current = $(this);
var val=parseInt(current.attr( "data-target" ));
if(val > maxVal){
maxVal=val;
}
});
console.log(maxVal);//Its the max value

Turak Vladyslav
below code will work you can check it once
var Lis = $('#test').find('li');
var dataArray = []
for(var i=0;i<Lis.length;i++){
dataArray.push($(Lis[i]).attr('data-target'))
}
var maxDatatTarget = Math.max.apply(null, dataArray)
alert("max data target value"+maxDatatTarget)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="test">
<li data-target="12">1</li>
<li data-target="4">2</li>
<li data-target="9">3</li>
<li data-target="15">4</li>
<li data-target="23">5</li>
<li data-target="32">6</li>
<li data-target="7">7</li>
<li data-target="10">8</li>
<li data-target="5">9</li>
<li data-target="2">10</li>
</ul>

Try this if it works for you :
function calculateMaxTarget(){
var attr[] = $('li').attr('data-target');
var max = 0;
for (var i=0; i < attr.length; i++) {
if(attr[i]>max){
max = attr[i];
}
};
return max;
}

Related

Sort UL numerically and alphabetically, using each items data-char value

I'm wanting to sort this UL numerically and alphabetically, using each items data-char value.
Note: I'm only wanting to sort the parent UL, not the child UL elements.
<ul>
<li data-char="w">
<span>W</span>
<ul>
<li>WWWWWWWWWWWWWW</li>
</ul>
</li>
<li data-char="5">
<span>5</span>
<ul>
<li>55555555555555</li>
</ul>
</li>
<li data-char="a">
<span>A</span>
<ul>
<li>AAAAAAAAAAAAAA</li>
</ul>
</li>
<li data-char="1">
<span>1</span>
<ul>
<li>11111111111</li>
</ul>
</li>
</ul>
I'm able to accomplish this with jQuery by doing:
function sortCharLi(a, b) {
var va = a.dataset.char.toString().charCodeAt(0),
vb = b.dataset.char.toString().charCodeAt(0);
// add weight if it's a number
if (va < 'a'.charCodeAt(0)) va += 100;
if (vb < 'a'.charCodeAt(0)) vb += 100;
return vb < va ? 1 : -1;
}
$('ul > li').sort(sortCharLi).appendTo('ul');
But I'm needing to remove the jQuery dependency so that's not an option any more.
Any ideas how I may do this without jQuery?
JSBIN
You can get the ul using getElemetsByTagName and children li can be get from the element object using children property.
function order(ul) {
// get html children elements of li
// in case of ul children will be li
// ` Array.from` will hell helps to convert them into array
var elements = Array.from(ul.children);
// sort them with the same code
elements.sort(function(a, b) {
var va = a.getAttribute('data-char').charCodeAt(0),
vb = b.getAttribute('data-char').charCodeAt(0),
charCA = 'a'.charCodeAt(0);
// add weight if it's a number
if (va < charCA) va += 100;
if (vb < charCA) vb += 100;
// just get the difference and return to sort them
return va - vb;
});
// append back to update the order
// forEach can be used to update since it's in array format
elements.forEach(function(ele) {
ul.appendChild(ele)
});
}
// get ul tag from dom and pass as parameter
// although you can use id selector or querySelector, etc
// it depends up on your need, here you just need to pass the dom reference of `ul` to be sorted
order(document.getElementsByTagName('ul')[0]);
<ul>
<li data-char="w">
<span>W</span>
<ul>
<li>WWWWWWWWWWWWWW</li>
</ul>
</li>
<li data-char="5">
<span>5</span>
<ul>
<li>55555555555555</li>
</ul>
</li>
<li data-char="a">
<span>A</span>
<ul>
<li>AAAAAAAAAAAAAA</li>
</ul>
</li>
<li data-char="1">
<span>1</span>
<ul>
<li>11111111111</li>
</ul>
</li>
</ul>
UPDATE :
If you want to use them in chain as in jQuery, then extend the prototype
NodeList.prototype.sortElements = function(custom) {
// if custom sort function passed then sort based on that
if (typeof custom === 'function')
return [].slice.call(this).sort(custom);
// otherwise apply sort method directly
return [].slice.call(this).sort();
// you can also use Array.from(this), which only works in latest browsers
}
Array.prototype.updateOrder = function() {
// iterate over array element
this.forEach(function(ele) {
// append to the parent element
ele.parentNode.appendChild(ele);
})
}
// sort them with the same code
function sortFn(a, b) {
var va = a.getAttribute('data-char').charCodeAt(0),
vb = b.getAttribute('data-char').charCodeAt(0),
charCA = 'a'.charCodeAt(0);
// add weight if it's a number
if (va < charCA) va += 100;
if (vb < charCA) vb += 100;
// just get the difference and return to sort them
return va - vb;
}
// get li elements which have `data-char` attribute
document.querySelectorAll('ul li[data-char]')
.sortElements(sortFn) // call sortElements methods we defined with custom sort function
.updateOrder(); // call updateOrder to update the order of element
<ul>
<li data-char="w">
<span>W</span>
<ul>
<li>WWWWWWWWWWWWWW</li>
</ul>
</li>
<li data-char="5">
<span>5</span>
<ul>
<li>55555555555555</li>
</ul>
</li>
<li data-char="a">
<span>A</span>
<ul>
<li>AAAAAAAAAAAAAA</li>
</ul>
</li>
<li data-char="1">
<span>1</span>
<ul>
<li>11111111111</li>
</ul>
</li>
</ul>
This function preserves your original sorter method. The function expects the ul element to be passed:
function sortThem(ul) {
var nodes = Array.prototype.slice.call(ul.childNodes).filter(function(el) {
// Could use QSA with scope depending on browser support here
return el.tagName === 'LI';
});
nodes.sort(function(a, b) {
var va = a.getAttribute('data-char').charCodeAt(0),
vb = b.getAttribute('data-char').charCodeAt(0);
// add weight if it's a number
if (va < 'a'.charCodeAt(0)) va += 100;
if (vb < 'a'.charCodeAt(0)) vb += 100;
return vb < va ? 1 : -1;
});
nodes.forEach(function(node) {
ul.appendChild(node);
});
}
You may use querySelectorAll for $('ul > li'). Pay attention, the right selector should be $('ul > li[data-char]') because you are inrested only in li tags having the data-char as attribute.
To convert the NodeList returned from querySelectorAll to array you can use Array.from.
To substitute the appendTo you may use forEach.
So the code could be:
function sortCharLi(a, b) {
var va = a.getAttribute('data-char').charCodeAt(0),
vb = b.getAttribute('data-char').charCodeAt(0);
// add weight if it's a number
if (va < 'a'.charCodeAt(0)) va += 100;
if (vb < 'a'.charCodeAt(0)) vb += 100;
return vb < va ? 1 : -1;
}
window.onload = function() {
// $('ul > li').sort(sortCharLi).appendTo('ul');
Array.from(document.querySelectorAll('ul > li[data-char]')).sort(sortCharLi).forEach(function(element, index) {
element.parentNode.appendChild(element);
});
}
<ul>
<li data-char="w">
<span>W</span>
<ul>
<li>WWWWWWWWWWWWWW</li>
</ul>
</li>
<li data-char="5">
<span>5</span>
<ul>
<li>55555555555555</li>
</ul>
</li>
<li data-char="a">
<span>A</span>
<ul>
<li>AAAAAAAAAAAAAA</li>
</ul>
</li>
<li data-char="1">
<span>1</span>
<ul>
<li>11111111111</li>
</ul>
</li>
</ul>
UPDATE
A shorter way to convert:
$('ul > li[data-char]').sort(sortCharLi).appendTo('ul');
to pure javaScript can be:
document.querySelectorAll('ul > li[data-char]').sort(sortCharLi).replaceWith();
In order to achieve this result the following methods have to be added:
NodeList.prototype.sort = function(callBack) {
if (typeof callBack === 'function') {
return [].slice.call(this).sort(callBack);
} else {
return [].slice.call(this).sort();
}
}
Array.prototype.replaceWith = function() {
this.forEach(function(element, index) {
element.parentNode.appendChild(element);
});
return this;
}
In this way there exist the possibility to chain methods like in jQuery:
function sortCharLi(a, b) {
var va = a.getAttribute('data-char').charCodeAt(0),
vb = b.getAttribute('data-char').charCodeAt(0);
// add weight if it's a number
if (va < 'a'.charCodeAt(0)) va += 100;
if (vb < 'a'.charCodeAt(0)) vb += 100;
return vb < va ? 1 : -1;
}
NodeList.prototype.sort = function(callBack) {
if (typeof callBack === 'function') {
return [].slice.call(this).sort(callBack);
} else {
return [].slice.call(this).sort();
}
}
Array.prototype.replaceWith = function() {
this.forEach(function(element, index) {
element.parentNode.appendChild(element);
});
return this;
}
window.onload = function () {
document.querySelectorAll('ul > li[data-char]').sort(sortCharLi).replaceWith();
}
<ul>
<li data-char="w">
<span>W</span>
<ul>
<li>WWWWWWWWWWWWWW</li>
</ul>
</li>
<li data-char="5">
<span>5</span>
<ul>
<li>55555555555555</li>
</ul>
</li>
<li data-char="a">
<span>A</span>
<ul>
<li>AAAAAAAAAAAAAA</li>
</ul>
</li>
<li data-char="1">
<span>1</span>
<ul>
<li>11111111111</li>
</ul>
</li>
</ul>
This is the best answer I can snap off from work, but it might need to be tailored to your html structure.
FUNCTION TO SORT UL WITHOUT JQUERY:
function sortUnorderedList(ul, sortDescending) {
if(typeof ul == "string")
ul = document.getElementById(ul);
// Idiot-proof, remove if you want
if(!ul) {
alert("The UL object is null!");
return;
}
// Get the list items and setup an array for sorting
var lis = ul.getElementsByTagName("LI");
var vals = [];
// Populate the array
for(var i = 0, l = lis.length; i < l; i++)
vals.push(lis[i].innerHTML);
// Sort it
vals.sort();
// Sometimes you gotta DESC
if(sortDescending)
vals.reverse();
// Change the list on the page
for(var i = 0, l = lis.length; i < l; i++)
lis[i].innerHTML = vals[i];
}
USAGE:
sortUnorderedList("ID_OF_LIST");

How to access all <li> whose id's begins with the same name

I want to access all tags with id="BasketProduct..."
HTML
<ul class ="productdetails">
<li id="BasketProduct-60">...</li>
<li id="BasketProduct-133">...</li>
<li id="BasketProduct-195">...</li>
<li id="BasketProduct-202">...</li>
</ul>
Edited:
var ul = document.getElementsByClassName('productdetails')[0],
i, temp;
for (i = 0; i < ul.children.length; i += 1) {
temp = ul.children[i].id;
if (temp.indexOf('BasketProduct-') > -1) {
// do smth
}
}

Selecting <li> to be added to an array

I have a list of <li> I was wondering how I can click and select them to be pushed onto my array.
For example,
<li class="browser_list">
<ul>
<li id="config_3"> Chrome 29</li>
<li id="config_4"> Chrome 31</li>
<li id="config_5"> Chrome 33</li>
<li id="config_6"> Chrome 35</li>
</ul>
</li>
array:
arr = [];
Can vary from size 0-4 depending on what I click
I want to be able to select or unselect (with highlighting) and add config_3, config_4, config_5, config_6 to an array for later use.
This is the solution in pure Javascript.
Alongside the snippet below, here's the same in a fiddle: http://jsfiddle.net/7qxs6hgj/
var list = document.getElementById('browser_list');
var items = list.getElementsByTagName('li');
var arr = [];
for (var i = 0; i < items.length; i++)
{
items[i].onclick = function(event)
{
if (this.className == 'selected')
{
this.className = 'unselected';
var idx = arr.indexOf(this.id);
if (idx >= 0)
arr.splice(idx, 1);
}
else
{
this.className = 'selected';
arr[arr.length] = this.id;
}
document.getElementById('arr').innerHTML = JSON.stringify(arr);
};
}
#browser_list li { cursor: pointer; }
.selected { background-color: #cccccc; }
.deselected { background-color: transparent; }
<ul id='browser_list'>
<li id="config_3"> Chrome 29</li>
<li id="config_4"> Chrome 31</li>
<li id="config_5"> Chrome 33</li>
<li id="config_6"> Chrome 35</li>
</ul>
<div id='arr'></div>
arr = []
$("#browser_list > ul").click(function(event){
if($(event.target).is("li")){
arr.push(event.target)
}
})
Toggle classes and check arrays:
var arr = [];
$(".browser_list ul li").click(function() {
$(this).toggleClass("active"); //add / remove class active;
var index = arr.indexOf(this.id)
if (index > -1) arr.splice(index, 1);
else arr.push(this.id)
});
And a fiddle: http://jsfiddle.net/2ymwdvrn/
Or if you need to get the list of ID's at a later point and dont want to keep a global array:
var arr = $(".browser_list ul li.active").map(function() {
return this.id;
}).get();
You have to do it this way:
$(function(){
$(".browser_list li").click(function(){
var arr = new Array();
$(this).toggleClass("selected");
$(".browser_list .selected").each(function(){
arr.push(this.id);
})
})
})
.selected
{
background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<li class="browser_list">
<ul>
<li id="config_3"> Chrome 29</li>
<li id="config_4"> Chrome 31</li>
<li id="config_5"> Chrome 33</li>
<li id="config_6"> Chrome 35</li>
</ul>
</li>

Jquery to sum values of all elements with specific attr value

I have this short menu:
<ul>
<li class="voucher">
Holidays (<span data="0" class="counter" id="119">0</span>)
<ul id="menu2">
<li class="voucher">
Travel deals (<span data="119" class="counter" id="123">1</span>)
</li>
<li class="voucher">
Hotel offers (<span data="119" class="counter" id="120">2</span>)
</li>
<li class="voucher">
Villas offers(<span data="119" class="counter" id="121">1</span>)
</li>
</ul>
</li>
</ul>
and this js which has to collect all subcategories values in () and add that sum as (value ) for the main category Holidays:
var sum = 0;
$('.counter').each(function () {
var counter = $(this).html();
var id = $(this).attr('id');
if (counter == 0) {
// here I want to find and sum all values in ( ) for span that has attr data equal to 119 which is the id of the main category Holidays
sum += parseInt($('span').find("[data='" + id + "']").html(), 10) || 0;
alert(sum);
//here I want the sum of all subcategories -Holidays ( 4 )
$(this).html(sum);
}
});
but it doesn't work.. No errors, just doesnt sum correct and returns always 0
Please help with this if you are OK with JS,
Here is jsfiddle:
http://jsfiddle.net/europe77/w1uL5a8o/1/
You are trying to find by data attribute in span object.You need to use:
parseInt($("span[data='" + id + "']").html());
Also there were other issue that needs to be addressed. Here is the full working code:
var sum = 0;
$('.counter').each(function () {
var counter = $(this).html();
var id = $(this).attr('id');
sum += parseInt($(this).html(), 10) || 0;
});
alert(sum);
$('.counter:eq(0)').html(sum);
Working Demo

how to sort by image src name for all LI under a UL?

I got a UL like this:
<ul id='mylist'>
<li id='1'><img src='kids.jpg'>kids.jpg</li>
<li id='2'><img src='apple.jpg'>apple.jpg</li>
<li id='3'><img src='toys.jpg'>toys.jpg</li>
<li id='4'><img src='love.jpg'>love.jpg</li>
</ul>
I want to sort it using jquery/javascript like this:
<ul id='mylist'>
<li id='2'><img src='apple.jpg'>apple.jpg</li>
<li id='1'><img src='kids.jpg'>kids.jpg</li>
<li id='4'><img src='love.jpg'>love.jpg</li>
<li id='3'><img src='toys.jpg'>toys.jpg</li>
</ul>
May I know how do I write the code?
$(document).ready(function() {
var ul = $('ul#mylist'),
li = ul.children('li');
li.detach().sort(function(a,b) {
return alphabetical($(a).children('img').attr('src'), $(b).children('img').attr('src'));
});
ul.append(li);
});
function alphabetical(a, b)
{
var A = a.toLowerCase();
var B = b.toLowerCase();
if (A < B){
return -1;
}else if (A > B){
return 1;
}else{
return 0;
}
}
<ul id='mylist'>
<li id='1'><img src='kids.jpg'>kids.jpg</li>
<li id='2'><img src='apple.jpg'>apple.jpg</li>
<li id='3'><img src='toys.jpg'>toys.jpg</li>
<li id='4'><img src='love.jpg'>love.jpg</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
var starting_array = new Array();
var temp_array = new Array();
for(var i = 1 ; i <= 4 ;i++){
starting_array[i] = $('#'+i).find('img').attr('src');
temp_array[i] = $('#'+i).find('img').attr('src');
}
temp_array.sort();
$('#mylist').html('');
var li_data = '';
for(var j=0; j< temp_array.length-1 ; j++ ){
var id = $.inArray(temp_array[j] ,starting_array);
li_data += '<li id="'+ id +'"><img src="'+ temp_array[j] +'" > '+ temp_array[j]+' </li>';
}
$('#mylist').html(li_data);
</script>
You can try this:
var items = $("#mylist > li").detach().get( );
items.sort( srcSort );
$("#mylist").append( items );
function srcSort( a, b ) {
var _a = $(a).children("img").prop("src").toUpperCase();
var _b = $(b).children("img").prop("src").toUpperCase();
if( _a > _b ) return 1;
if( _a < _b ) return -1;
return 0;
}
fiddle here

Categories

Resources