1

I have a list of meeting days, e.g. Monday morning, Monday afternoon, Monday evening, Tuesday morning and so on which are then displayed on a website's front end as an unordered list. Because the text is not alphabetical I want to sort the items using IDs I have created for each based on their item aliases with an added prefix. E.g. the "monday-morning" alias is now "aa-monday-morning" and that in turn is used to create id="aa-monday-morning" Each of the list items has the class "sort" and sits in a ul with the id "meetings". [I do realise that if they'd been set up in the correct order in the first place, I wouldn't have a problem, but it's too late, now as there are 100+ items tagged with those list items].

I understand that I need to select all the items with the class name "sort" and then convert them to an array before sorting them by their ids, but I am really struggling.

I started with some code I copied from somewhere but it doesn't seem to do anything and I'm not sure why.

let List = document.getElementById("meetings");
let listItems = List.getElementsByClassName('sort');
    sortList = Array.prototype.slice.call(listItems);
    if(listItems && listItems.length){
        listItems.sort(sortList);
        while (List.hasChildNodes()) {
            List.removeChild(List.lastChild);
        }
        while(listItems.length){
            var newList = listItems.shift();
            List.appendChild(newList);
        }
    }
function sortList(a, b){
    var aid = (a.id);
    var bid = (b.id);
    return aid - bid;
}
<ul id="meetings" class="sidebar">
<li id="aa-monday-morning" class="sort">Monday morning</li>
<li id="ba-tuesday-morning" class="sort">Tuesday morning</li>
<li id="bc-tuesday-evening" class="sort">Tuesday evening</li>
<li id="cc-wednesday-evening" class="sort">Wednesday evening</li>
<li id="dc-thursday-evening" class="sort">Thursday evening</li>
<li id="fb-friday-afternoon" class="sort">Friday afternoon</li>
<li id="ca-wednesday-morning" class="sort">Wednesday morning</li>
<li id="bb-tuesday-afternoon" class="sort">Tuesday afternoon</li>
<li id="cb-wednesday-afternoon" class="sort">Wednesday afternoon</li>
<li id="ac-monday-evening" class="sort">Monday evening</li>
<li id="ab-monday-afternoon" class="sort">Monday afternoon</li>
</ul>

The end result should be:

    <ul id="meetings" class="sidebar">
    <li id="aa-monday-morning" class="sort">Monday morning</li>
    <li id="ab-monday-afternoon" class="sort">Monday afternoon</li>
    <li id="ac-monday-evening" class="sort">Monday evening</li>
    <li id="ba-tuesday-morning" class="sort">Tuesday morning</li>
    <li id="bb-tuesday-afternoon" class="sort">Tuesday afternoon</li>
    <li id="bc-tuesday-evening" class="sort">Tuesday evening</li>
    <li id="ca-wednesday-morning" class="sort">Wednesday morning</li>
    <li id="cb-wednesday-afternoon" class="sort">Wednesday afternoon</li>
    <li id="cc-wednesday-evening" class="sort">Wednesday evening</li>
    <li id="dc-thursday-evening" class="sort">Thursday evening</li>
    <li id="fb-friday-afternoon" class="sort">Friday afternoon</li>
    </ul>

Thank you for reading.

1
  • @ControlAltDel the fifth line in the JS is listItems.sort(sortList); which sorts the array in-place. The result does not have to be (re)assigned. Commented Dec 6, 2022 at 19:22

2 Answers 2

4

You can create a variable for the parent element of the list items listElement and another that holds an array of the list items listItemElements.

Sort the array according to your criteria: read about the compare callback function argument that is provided to array.sort().

Finally, (re-)insert the list item elements into the parent element in the new, sorted order.

Here's a complete code example:

const listElement = document.getElementById('meetings');

const listItemElements = [...listElement.querySelectorAll(':scope > li.sort')];

listItemElements.sort(({id: a}, {id: b}) => a < b ? -1 : a > b ? 1 : 0);

for (const li of listItemElements) listElement.appendChild(li);
<ul id="meetings" class="sidebar">
<li id="aa-monday-morning" class="sort">Monday morning</li>
<li id="ba-tuesday-morning" class="sort">Tuesday morning</li>
<li id="bc-tuesday-evening" class="sort">Tuesday evening</li>
<li id="cc-wednesday-evening" class="sort">Wednesday evening</li>
<li id="dc-thursday-evening" class="sort">Thursday evening</li>
<li id="fb-friday-afternoon" class="sort">Friday afternoon</li>
<li id="ca-wednesday-morning" class="sort">Wednesday morning</li>
<li id="bb-tuesday-afternoon" class="sort">Tuesday afternoon</li>
<li id="cb-wednesday-afternoon" class="sort">Wednesday afternoon</li>
<li id="ac-monday-evening" class="sort">Monday evening</li>
<li id="ab-monday-afternoon" class="sort">Monday afternoon</li>
</ul>

Sign up to request clarification or add additional context in comments.

2 Comments

I had a similar need, but have to use a data-attribute. How might I use a data attribute instead of an ID? Simply swapping id in your sort statement doesn’t do what I expected, and I tried listItemElements.sort(({'data-built': a}, {'data-built': b}) => a < b ? -1 : a > b ? 1 : 0); with no result
^ @J.Hogue Why would you try to destructure data-* attributes directly? You'll need to access them on the dataset property instead — e.g. array.sort(({ dataset: { locale: a } }, { dataset: { locale: b } }) => a < b ? -1 : a > b ? 1 : 0)
0

You can use the following approach:

```
function sortById(){
  const result=document.getElementsByClassName("sort");
  let arr=[];
  for(const item of result){
       arr.push(item.id)
  }

  let sortedArr=arr.sort((a,b)=>a>b);
  return sortedArr;
}
```

1 Comment

This didn't work for me, I'm afraid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.