hnnnng
hnnnng

Reputation: 495

Sort lists in multiple divs with vanilla JS

I have multiple list located in separated divs. As of now each list has its own random ordering, is there a way to sort them all in alpha order WITHOUT moving them our of their div parents?

This is how my markup looks like:

<div class="cnf-co-chair">
    <ul>
        <li>H</li>
        <li>B</li>
    </ul>
</div>
<div class="cnf-chair">
    <ul>
        <li>A</li>
        <li>G</li>
        <li>C</li>
    </ul>
</div>
<div class="cnf-member">
    <ul>
        <li>D</li>
        <li>F</li>
        <li>E</li>
    </ul>
</div>

I would like the ordering of the items changed to this order instead:

<div class="cnf-co-chair">
    <ul>
        <li>A</li>
        <li>B</li>
    </ul>
</div>
<div class="cnf-chair">
    <ul>
        <li>C</li>
        <li>D</li>
        <li>E</li>
    </ul>
</div>
<div class="cnf-member">
    <ul>
        <li>F</li>
        <li>G</li>
        <li>H</li>
    </ul>
</div>

I tried this but it only changes the ordering of the first list in the first div:

var listToModify = document.querySelector("ul");
var listItemsToShuffle = listToModify.querySelectorAll("li");
for (var i = 0; i < listItemsToShuffle.length - 1; i++) {
    listToModify.appendChild(listItemsToShuffle[i]);
}

I am open to use jQuery as long as the location of list items doesn't change in their parent div.

Upvotes: 0

Views: 222

Answers (1)

Brother58697
Brother58697

Reputation: 3178

What I did was:

  • Get an HTML collection of the elements
  • Convert it to an array of elements
  • Shallow copy that array, and sort it
  • Loop through the original array and set each element's outer HTML, based on its index, to the outer HTML of the equivalent element in the sorted array.
    • Outer HTML preserves attributes like classes, ID, etc

const listItems = document.querySelectorAll('li')
const itemArray = [...listItems]
const sortedArray = [...itemArray].sort((a,b)=> {
    return a.textContent < b.textContent ? -1 
      : a.textContent > b.textContent ? 1 
      : 0
  })
  
itemArray.forEach((element, i) => element.outerHTML = sortedArray[i].outerHTML)
<div class="cnf-co-chair">
    <ul>
        <li>H</li>
        <li>B</li>
    </ul>
</div>
<div class="cnf-chair">
    <ul>
        <li class="asd">A</li>
        <li>G</li>
        <li>C</li>
    </ul>
</div>
<div class="cnf-member">
    <ul>
        <li>D</li>
        <li>F</li>
        <li>E</li>
    </ul>
</div>

Upvotes: 2

Related Questions