I have divs with data attribute data-submit-date and i want to sort them based on the value of this attribute which is date format.
here's the code for one of the divs:
<div class="article" data-submit-date="2017-09-12T05:45:36.951Z">
<h1>aaaaA</h1>
</div>
my attempts:
$divss = $(".article");
var alphaOrderDivs = $divss.sort(function (a, b) {
return $(a).data("submit-date") > $(b).data("submit-date");
});
$(".articles").html(alphaOrderDivs);
I replaced this line $(a).data("submit-date") with Date.parse($(a).data("submit-date")) but it fails. Can anyone help me?
Thank In Advance
Try the following
var articles = $.makeArray($(".article"));
articles.sort(function(a, b) {
return new Date($(a).data("submit-date")) < new Date($(b).data("submit-date"));
});
Snippet
var articles = $.makeArray($(".article"));
articles.sort(function(a, b) {
return new Date($(a).data("submit-date")) < new Date($(b).data("submit-date"));
});
console.log(articles);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="article" data-submit-date="2017-09-10T05:45:36.951Z">
<h1>aaaaA</h1>
</div>
<div class="article" data-submit-date="2017-09-12T05:45:36.951Z">
<h1>aaaaA</h1>
</div>
<div class="article" data-submit-date="2017-09-11T05:45:36.951Z">
<h1>aaaaA</h1>
</div>
Use the getTime() method as follows:
$divss = $(".article");
var alphaOrderDivs = $divss.sort(function (a, b) {
return new Date($(a).data("submit-date")).getTime() > new Date($(b).data("submit-date")).getTime();
});
$(".articles").html(alphaOrderDivs);
The getTime() method of the Date object will parse your time into milliseconds and will hence help you compare them.
Related
I'm trying to order the different products from a website but can't do it correctly.
Basically I need to get the price of each one and order them from the most expensive one to the least one.
I tried the following code but it disappears everything and keeps not ordering them in the correct way:
var divList = $(".block-level.h2");
divList.sort(function(a, b){
return $(a).data(".block-level.h2")-$(b).data(".block-level.h2")
});
$(".grid").html(divList);
I don't have access to modify the HTML so it has to be done with the code I have now, only can add things through jQuery.
Can someone give me a tip or help me out please?
Thank you.
For your request to sort the product grid items, here is the jQuery code that you can use.
var values = [];
$('.block-level.h2').each(function() {
var temp = Array();
temp['value'] = parseInt($(this).html().replace('$',''));
temp['element'] = $(this).closest('.grid-item');
values.push(temp);
});
values.sort(function(a,b) { return b.value - a.value; });
var sortedHtml = '';
$.each(values, function(index, obj) {
if((index+1)%3==1) {
sortedHtml+=('<div class="grid product-cards__row"><div class="grid-item one-third palm-one-whole product-cards__item">'+$(obj.element).html()+'</div>');
} else if((index+1)%3==0) {
sortedHtml+=('<div class="grid-item one-third palm-one-whole product-cards__item">'+$(obj.element).html()+'</div></div>');
} else {
sortedHtml+=('<div class="grid-item one-third palm-one-whole product-cards__item">'+$(obj.element).html()+'</div>');
}
});
$('.product-cards').html(sortedHtml);
Hope this helps!
You can achieve this by the following code-
var values = Array();
$('.block-level.h2').each(function() {
values.push(parseInt($(this).html().replace('$','')));
});
values.sort(function(a, b){return b-a});
In your code above - the main problem is with $(a).data(".block-level.h2") since its trying to find an attribute with name data-.block-level.h2 in element a which doesn't exist. That's why the empty result.
I have the following html structur (endless):
<div class="wrapper">
<div class="content"> Its block 3
<div class="number">3</div>
</div>
</div>
<div class="wrapper">
<div class="content"> Its block 2
<div class="number">2</div>
</div>
</div>
I want to sort it by clicking a button like this:
<div class="wrapper">
<div class="content"> Its block 2 <--- new order
<div class="number">2</div> <--- new order
</div>
</div>
<div class="wrapper">
<div class="content"> Its block 3 <--- new order
<div class="number">3</div> <--- new order
</div>
</div>
... but with my script it doesn´t work (because of the same div class name, I think?). So, how can I sort this and toggle the sort by highest number and lowest number? Can anybody help me?
function sortHigh(a, b) {
var date1 = $(a).find(".content .number").text()
var date2 = $(b).find(".content .number").text();
return $(a).find(".content .number").text() > $(b).find(".content .number").text();
};
function sortLow(a, b) {
var date1 = $(a).find(".content .number").text()
var date2 = $(b).find(".content .number").text();
return $(a).find(".content .number").text() < $(b).find(".content .number").text();
};
//how to toggle?
$(function () {
$('.sort').click(function () {
$('.content').sort(sortHigh).appendTo('.wrapper');
}, function () {
$('.content').sort(sortLow).appendTo('.wrapper');
});
});
Thats my bad try: fiddle
try to change your code with this:-
var toggle="high";
//how to toggle?
$(function(){
$('.sort').click(function () {
if (toggle == "high") {
toggle = "low";
$('.list').html($('.list .wrapper').sort(sortLow));
} else {
toggle = "high"
$('.list').html($('.list .wrapper').sort(sortHigh));
}
});
});
Demo
Using jQuery, you can add the sort functionality as such:
jQuery.fn.sortDomElements = (function() {
return function(comparator) {
return Array.prototype.sort.call(this, comparator).each(function(i) {
this.parentNode.appendChild(this);
});
};
})();
var srtdesc = true;
$(function() {
$(".sort").click(function() {
srtdesc = !srtdesc;
$(".list").children().sortDomElements(function(a, b) {
if (srtdesc) {
return Number($(a).find('.number').text()) - Number($(b).find('.number').text());
} else {
return Number($(b).find('.number').text()) - Number($(a).find('.number').text());
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="sort">Sort-Button</button>
<div class="list">
<div class="wrapper">
<div class="content">Its block 3
<div class="number">3</div>
</div>
</div>
<div class="wrapper">
<div class="content">Its block 1
<div class="number">1</div>
</div>
</div>
<div class="wrapper">
<div class="content">Its block 2
<div class="number">2</div>
</div>
</div>
</div>
You have two issues with your code.
The first is that your sorts are sorting strings. return "2" > "3" for example.
The other issue is that the click function you're using isn't toggling correctly. I'm guessing you're familiar with the .hover() syntax which is why you've done it that way.
As you can see, I'm forcing sortHigh and sortLow to return Numbers. I've also done a sorting low/high check and toggle within the click function.
function sortHigh(a, b) {
var date1 = Number($(a).find(".number").text());
var date2 = Number($(b).find(".number").text());
return date1 > date2;
};
function sortLow(a, b) {
var date1 = Number($(a).find(".number").text());
var date2 = Number($(b).find(".number").text());
return date1 <= date2;
};
$(function(){
var sortHighCheck = null;
$('.sort').click(function(){
if (sortHighCheck === true) {
$('.wrapper').sort(sortLow).appendTo('.list')
sortHighCheck = false;
} else {
$('.wrapper').sort(sortHigh).appendTo('.list')
sortHighCheck = true;
}
});
});
Edit: Forgot to add the jsfiddle link
If you want to sort, you can add data-val attribute to each content div:
<div class="content" data-val="2"> Its block 2 <--- new order
and sort each wrapper div with this code:
jQuery("#sort").click( function() {
jQuery('.wrapper').sort(function (a, b) {
return jQuery(a).find('.content').data('val') - jQuery(b).find('.content').data('val');
}).each(function (_, container) {
jQuery(container).parent().append(container);
});
});
Trying to sort children div based on data attributes
The html code below is being generated by a CM and the data can be retrieved in any random order.
the html code is
<section class="box explore">
<div id="ProductContainer" class="row">
<div id="1232132" data-name="B" data-category="Category_A" class="explore-cell">
<h>B</h>
<p>Category_A</p>
</div>
<div id="123" data-name="A" data-category="Category_A" class="explore-cell">
<h>A</h>
<p>Category_A</p>
</div>
<div id="1232152351" data-name="C" data-category="Category_A" class="explore-cell">
<h>C</h>
<p>Category_A</p>
</div>
<div id="12342341" data-name="E" data-category="Category_B" class="explore-cell">
<h>E</h>
<p>Category_B</p>
</div>
<div id="1325321" data-name="D" data-category="Category_B" class="explore-cell">
<h>D</h>
<p>Category_B</p>
</div>
</div>
java
$('div').sort(function (a, b) {
var contentA = $(a).attr('data-name');
var contentB = $(b).attr('data-name');
return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
})
Jsfiddle http://jsfiddle.net/w8gkshue/
if someone can point me in the right direct on how to best sort either by Product Name or Category.
Updated hope this gives better explination
EDIT: I missed the jQuery tag... leaving the answer still.
var productCt = document.getElementById('ProductContainer'),
reInsertProductCt = tempRemove(productCt);
[].slice.call(productCt.children)
.sort(function (a, b) {
var aName = a.dataset.name,
bName = b.dataset.name;
return aName < bName? -1 : +(aName > bName);
})
.forEach(productCt.appendChild.bind(productCt));
reInsertProductCt();
function tempRemove(el) {
var parent = el.parentNode,
nextSibling = el.nextSibling;
parent.removeChild(el);
return function () {
if (nextSibling) parent.insertBefore(el, nextSibling);
else parent.appendChild(el);
};
}
<div id="ProductContainer" class="row">
<div id="1232132" data-name="B" data-category="Category_A" class="explore-cell">
<h>TEST NAME B</h>
<p>TEST</p>
</div>
<div id="123" data-name="A" data-category="Category_A" class="explore-cell">
<h>TEST NAME A</h>
<p>TEST</p>
</div>
<div id="1232152351" data-name="C" data-category="Category_A" class="explore-cell">
<h>TEST NAME C</h>
<p>TEST</p>
</div>
<div id="12342341" data-name="E" data-category="Category_B" class="explore-cell">
<h>TEST NAME E</h>
<p>TEST</p>
</div>
<div id="1325321" data-name="D" data-category="Category_B" class="explore-cell">
<h>TEST NAME D</h>
<p>TEST</p>
</div>
</div>
You can use .sort method like this
var $wrapper = $('#ProductContainer');
$wrapper.find('.explore-cell').sort(function (a, b) {
return a.getAttribute('data-name') > b.getAttribute('data-name');
})
.appendTo( $wrapper );
But I don't sure about the cross browsing support
Calling only sort on them won't actually visually change the DOM, it just returns a sorted collection. So basically you just need to get the collection, sort it, then return it. Something like this should work:
$('#ProductContainer > div').detach().sort(function (a, b) {
var contentA = $(a).data('name');
var contentB = $(b).data('name');
return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
}).appendTo('#ProductContainer');
You'll want to make sure that you use the detach() method and not remove(), as detach() will retain all of the data and events associated with the collection items.
Why choose to sort by category or by name when you can sort by both?
I tried to write a generic multisort function generator, which should also work with the native array sort function.
JSFIDDLE HERE
A function that generates the multisort, it takes two parameters.
The column priority list order (first by category or by name? You decide).
I also wanted a way to provide values for columns (since you might not retrieve them the same way for each of them), it is an object that describes for each column a function to retrieve data.
Here it is
function getMultisortFn(columns, provideColumnData) {
return function (a, b) {
for (var i = 0, l = columns.length; i < l; i++) {
var column = columns[i];
var aColumnData = provideColumnData[column.name](a, column.name);
var bColumnData = provideColumnData[column.name](b, column.name);
if (aColumnData !== bColumnData) {
if (column.asc) {
return String.prototype.localeCompare.call(aColumnData, bColumnData);
}
return String.prototype.localeCompare.call(bColumnData, aColumnData);
}
}
};
}
Now this is the part where you actually use the multisort generated
function retrieveDataAttribute(item, attribute) {
return $(item).data(attribute);
}
var $container = $('#ProductContainer');
var $products = $container.find('div');
var multisort = getMultisortFn([{
name: 'category',
asc: false
}, {
name: 'name',
asc: true
}], {
name: retrieveDataAttribute,
category: retrieveDataAttribute
});
$products.sort(multisort);
And finally the DOM manipulation to apply the new order
$products.detach().appendTo($container);
EDIT thanks to plalx:
$container.detach().append($products).appendTo('section.box.explore');
My javascript
var currentMonth= new Date().getMonth();
if (demo.length >= currentMonth){
var d3data = demo[currentMonth];
// output will be ["23", "19"]
now i need to update output values to #donut and #donut1 (data-donut="")
values are coming from json it may change according to month
for reference i have added FIDDLE
http://jsfiddle.net/Qh9X5/3166/
<div class="zipper">
<div class="current">
<div class="title_text">current</div>
<div id="donut" data-donut="42"></div>///here in the data-donut value
</div>
<div class="target">
<div class="title_text">Target</div>
<div id="donut1" data-donut="62"></div>
</div>
</div>
Any help is Appreciated
You can use this to assign the values from the array (assuming the array is the result after parsing it from json)
var d3data = demo[currentMonth];
// assuming that this results in d3data = ["23", "19"];
$(document).ready(function() {
$("div[data-donut]").each(function(i) {
$(this).attr('data-donut', d3data[i]);
});
});
The first value of the array will be assigned to the first div and the second value to the second one.
See JSFiddle
Looks like you want to modify the data-donut attribute of the divs. Hope this will help
document.getElementsById("donut").setAttribute("data-donut","<your value>");
document.getElementsById("donut1").setAttribute("data-donut","<your value>");
This will work
obj = ["23", "19"];
var keys = Object.keys(obj);
for (var i = 0,j=1; i < keys.length; i++,j++) {
var val = obj[keys[i]];
document.getElementById("donut"+j).setAttribute("data-donut", val);
}
<div class="zipper">
<div class="current">
<div class="title_text">current</div>
<div id="donut1" data-donut="42"></div>///here in the data-donut value
</div>
<div class="target">
<div class="title_text">Target</div>
<div id="donut2" data-donut="62"></div>
</div>
</div>
This is not json format ["23", "19"]
e.g this is an array
var d3data = ["23", "19"];
$('#donut').data('donut', d3data[0]);
$('#donut1').data('donut',d3data[1]);
Following is the repetivite html structure that i have in my template:
<div class="mystyle" data-id= "11002">
<div class="style1-header"><h6>Change Status of Task</h6></div>
<p class="style1-content">Seriously Change Status of Task</p>
<p class="style2-content" style="visibility:hidden">12</p>
</div>
The above is the html structure that keeps repeating in my html template. I wanted these things to be sorted based on the numbers 12 as in the above case.
How can i do it with jquery. The fiddle is available here.
Use JavaScript's Array.sort method to sort an array of the divs.
var $divs = $('div.mystyle').get().sort(function(a,b){
var aKey = +$(a).find('p.style2-content').text(),
bKey = +$(b).find('p.style2-content').text();
return aKey - bKey;
});
Then append the now sorted array to the DOM.
$('body').append($divs);
var $elements = $("div.mystyle");
function sortFn(a, b) {
var aText = $(a).find("p:hidden").text();
var bText = $(a).find("p:hidden").text();
return aText > bText ? 0 : 1;
}
$elements.sort(sortFn);