Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: Sort li items alphabetically by data attribute without jquery

Tags:

javascript

I'm trying to sort a list alphabetically only using javascript.

I've already none a similar function using jquery like this:

$('.articles').append($('#articles-non-attached li'));
        var alphabeticallyOrderedDivs = $('.articles li').sort(function(a, b) {
            return String.prototype.localeCompare.call($(a).data('title').toLowerCase(), $(b).data('title').toLowerCase());
        });

But now I need to use just Javascript.

So far I've got:

var stores_li = document.querySelectorAll('.store-list-item');

//stores_li.sort();

[].slice.call(stores_li).sort(function(a, b) {
    var textA = a.getAttribute('data-title').toLowerCase()
    var textB = b.getAttribute('data-title').toLowerCase()
    return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
    //return String.prototype.localeCompare.call(textA,textB);

});
<ul>
  <li class="store-list-item" data-title="a">Test 1</li>
  <li class="store-list-item" data-title="c">Test 3</li>
  <li class="store-list-item" data-title="b">Test 2</li>
  <li class="store-list-item" data-title="d">Test 4</li>
</ul>
like image 539
Cátia Rodrigues Avatar asked Dec 11 '25 14:12

Cátia Rodrigues


1 Answers

You need to append the newly sorted items.

var stores_li = document.querySelectorAll('.store-list-item');

[].slice.call(stores_li).sort(function(a, b) {
    var textA = a.getAttribute('data-title').toLowerCase()
    var textB = b.getAttribute('data-title').toLowerCase()
    return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
})
  .forEach(function(el) {el.parentNode.appendChild(el)});
<ul>
  <li class="store-list-item" data-title="a">Test 1</li>
  <li class="store-list-item" data-title="c">Test 3</li>
  <li class="store-list-item" data-title="b">Test 2</li>
  <li class="store-list-item" data-title="d">Test 4</li>
</ul>

This is because the native .sort() method isn't a DOM method; it just sorts any arbitrary list of Array items. So by appending the newly sorted item, it commits the new element order to the DOM.

Note that the simple solution above assumes they all share the same parent.


Here's a version with modern syntax and methods:

var stores_li = document.querySelectorAll('.store-list-item');

Array.from(stores_li).sort((a, b) =>   
  a.dataset.title.toLowerCase().localeCompare(b.dataset.title.toLowerCase())
)
  .forEach(el => el.parentNode.appendChild(el));
<ul>
  <li class="store-list-item" data-title="a">Test 1</li>
  <li class="store-list-item" data-title="c">Test 3</li>
  <li class="store-list-item" data-title="b">Test 2</li>
  <li class="store-list-item" data-title="d">Test 4</li>
</ul>
like image 166
llama Avatar answered Dec 14 '25 04:12

llama