user10354541
user10354541

Reputation:

Sort alphaNumeric HTML list

I need to sort an alphaNumeric list. I am able to sort but some how because it is alphaNumeric, I am not able to put the abc1 before the abc10.

My HTML Code:

<ul class="theList">
   <li><b>abc11:</b>Hello</li>
   <li><b>abc10:</b>Hello</li>
   <li><b>xyz24:</b>Hello</li>
   <li><b>abc1:</b>Hello</li>
   <li><b>xyz2:</b>Hello</li>
</ul>

My JavaScript:

  $(document).ready(function() {
    var list, i, switching, b, shouldSwitch;
    list = document.getElementsByClassName("theList");
    for (var j = 0; j < list.length; j++) {
      switching = true;
      while (switching) {
        switching = false;
        b = list[j].getElementsByTagName("li");
        for (i = 0; i < (b.length - 1); i++) {
          shouldSwitch = false;
          if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
            shouldSwitch = true;
            break;
          }
        }
        if (shouldSwitch) {
          b[i].parentNode.insertBefore(b[i + 1], b[i]);
          switching = true;
        }
      }
    }
  });

My Result:

Expected Result:

What am I missing?

Upvotes: 2

Views: 278

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371233

It would probably be a lot easier to sort the lis in their own array, outside of the document, and then append them to the ul again in the correct order. You can use localeCompare to check which string comes first lexicographically, no jQuery required:

const theList = document.querySelector('.theList');
const lis = Array.from(theList.children);
const firstText = elm => elm.children[0].textContent;
lis.sort((a, b) => firstText(a).localeCompare(firstText(b)));
lis.forEach(li => theList.appendChild(li));
<ul class="theList">
   <li><b>abc11:</b>Hello</li>
   <li><b>abc10:</b>Hello</li>
   <li><b>xyz24:</b>Hello</li>
   <li><b>abc1:</b>Hello</li>
   <li><b>xyz2:</b>Hello</li>
</ul>

To sort multiple such lists, iterate over a querySelectorAll:

document.querySelectorAll('.theList').forEach((theList) => {
  const lis = Array.from(theList.children);
  const firstText = elm => elm.children[0].textContent;
  lis.sort((a, b) => firstText(a).localeCompare(firstText(b)));
  lis.forEach(li => theList.appendChild(li));
});
<ul class="theList">
   <li><b>abc11:</b>Hello</li>
   <li><b>abc10:</b>Hello</li>
   <li><b>xyz24:</b>Hello</li>
   <li><b>abc1:</b>Hello</li>
   <li><b>xyz2:</b>Hello</li>
</ul>

<ul class="theList">
   <li><b>abc11:</b>Hello</li>
   <li><b>abc10:</b>Hello</li>
   <li><b>xyz24:</b>Hello</li>
   <li><b>abc1:</b>Hello</li>
   <li><b>xyz2:</b>Hello</li>
</ul>

Upvotes: 1

Related Questions