Sorting an HTML Collection with Javascript
By: Chris Hosler
Tags: JavaScript, HTML, Sorting

Must…sort….

While working on a project, involving a Rails API and a Javascript front-end, I had a database of around 100 items being rendered on the front-end. The data was all being posted to the front-end just fine and everything was working. However, the data was all being posted to the front-end based on the database ID of the seed data, this was fine…but it really bugged me that it was just seemingly random on the page.

So even though it had no effect on what I wanted my project to do, I decided that I wanted to sort it! Now this may not be the best or most efficient solution to my sort problem, but it’s the one that I got to work for me and I was pretty happy with it.

Now in my project the data that I wanted to sort was being rendered in a container class and being created as a <div> card, so the first step was to just create my sort function and grab the cards:

function sorting(){

container=document.querySelector(‘#all-games-container’)

var divCard = container.children

Easy enough, define my function, declared a variable for my container, and they declared another value for my <div> cards. Next, after some research I found that there really wasn’t a way to directly sort the cards as they were, so the solution was to convert my collected HTML elements into an array using the Array.prototype.slice() method:

divCard = Array.prototype.slice.call(divCard)

Now with the Array.prototype.slice() method essentially allows you to take elements from one array and add them to another array, in my case, it can , rather conveniently, take array-like objects and covert them into an actual array. Hurray!

Now that I had all of <div> cards inside of an array, I can use array methods on them! So this means that I can now use .sort to help me arrange all of those pesky <div> cards:

divCard.sort(function(a, b) {

if (a.textContent < b.textContent) {

return -1;

} else {

return 1;}

})

Basically, just going through all of the items in my array comparing the textContent of each item and sorting them in alphabetical order.

So now that I had my array in alphabetical order, all I have to do yet is put my <div> cards back onto my front-end. For the next step, I just cleared out the container holding all my cards, using the variable that I had assigned earlier, by assigning its innerHTML as an empty string: container.innerHTML = ""; . That way I had a clean slate to put all of my freshly arranged cards.

The final step was to go back through my array, take each element, append it back into my container, I accomplished this with a simple For loop to iterate over my array:

for(var i = 0, l = divCard.length; i < l; i++) {

container.appendChild(divCard[i]);

}

That’s it! I now had all of elements in a nice alphabetical order, or so I thought. The trouble now became where I ran my nice sort function, since in my program I was using a fetch to gather my data from the database, trying to run sort as part of the fetch would cause the sort function to run before the promise was resolved.

At this point I had spent a little more time than I had expected to, just to satisfy my own idiosyncrasies. So I resolved to tie my function into a button, not exactly what I had set out to do, but at least now I could sort my data at the press of a button!

And for you, just to tie everything together here is all of my code together:

document.addEventListener('click', function(e){

if (e.target.matches('#sort'){

e.preventDefault()

sorting()} //added a click listener to my sort button

.

.

.

. function sorting(){

container=document.querySelector('#all-games-container') var divCard = container.children divCard = Array.prototype.slice.call(divCard) divCard.sort(function(a, b) {

if (a.textContent < b.textContent) {

return -1;

} else {

return 1;

}

})

container.innerHTML = ""; for(var i = 0, l = divCard.length; i < l; i++) {

container.appendChild(divCard[i]);}

}

I hope that this helps, and thank you for reading.