What about getting all of the list items, push them into array which later will be sorted?
var allListElements = document.getElementById("staff").getElementsByTagName("li");
var staff = new Array();
for (i = 0; i < allListElements.length; i++) {
staff.push(allListElements[i].getAttribute('data-azsort'));
}
staff.sort(function(a, b) {
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
//Print
document.write('<h4>Sorted</h4>');
for (i = 0; i < staff.length; i++) {
document.write(staff[i] + "<br />");
}
<h4>Input</h4>
<ul id="staff">
<li data-azsort="smithjohn">
<a href="#">
<span class="list-name">John Smith</span>
</a>
<span class="list-desc">Professor</span>
</li>
<li data-azsort="barnestom">
<a href="#">
<span class="list-name">Tom Barnes</span>
</a>
<span class="list-desc">Lecturer</span>
</li>
</ul>
Additionally you can save the index of <li>
and reorder the <ul>
.
This works for any number of lists: it basically gathers all li
s in ul
s that have your attribute, sorts them according to their data-*
attribute value and re-appends them to their parent.
Array.from(document.querySelectorAll("ul > li[data-azsort]"))
.sort(({dataset: {azsort: a}}, {dataset: {azsort: b}}) => a.localeCompare(b)) // To reverse it, use `b.localeCompare(a)`.
.forEach((item) => item.parentNode.appendChild(item));
<ul>
<li data-azsort="skeetjon">
<a href="#"><span class="list-name">Jon Skeet</span></a>
<span class="list-desc">Stack Overflow user</span>
</li>
<li data-azsort="smithjohn">
<a href="#"><span class="list-name">John Smith</span></a>
<span class="list-desc">Professor</span>
</li>
<li data-azsort="barnestom">
<a href="#"><span class="list-name">Tom Barnes</span></a>
<span class="list-desc">Lecturer</span>
</li>
</ul>
<ul>
<li data-azsort="smithjohn">
<a href="#"><span class="list-name">John Smith</span></a>
<span class="list-desc">Professor</span>
</li>
<li data-azsort="barnestom">
<a href="#"><span class="list-name">Tom Barnes</span></a>
<span class="list-desc">Lecturer</span>
</li>
<li data-azsort="skeetjon">
<a href="#"><span class="list-name">Jon Skeet</span></a>
<span class="list-desc">Stack Overflow user</span>
</li>
</ul>
The funny thing is, it gets all li
s in the same array, sorts them all, but in the end figures out which list the li
originally belonged to. It’s a pretty simple and straight-forward solution.
A slightly longer ECMAScript 5.1 alternative would be:
Array.prototype.slice.call(document.querySelectorAll("ul > li[data-azsort]")).sort(function(a, b) {
a = a.getAttribute("data-azsort");
b = b.getAttribute("data-azsort");
return a.localeCompare(b);
}).forEach(function(node) {
node.parentNode.appendChild(node);
});
You can pass a comparison function to Array.prototype.sort
you should be able to do something like
$items = $('li[data-azsort]');
var compareElem = function (a, b) {
if (a.attr('data-azsort') > b.attr('data-azsort') {
return 1;
} else {
return -1
}
};
Array.prototype.sort.apply($items, compareElem);