skip to Main Content

I want to re-order several ul-list on my web.
Each ul with the same class should be in numerical order after using javascript.

The list may look like below

$(document).ready(function() {
  var ul = $('ul.filelist');
  for (let u = 0; u < ul.length; u++) {
    const element = ul[u];

    li = element.querySelectorAll('li');

    li.detach().sort(function(a, b) {
      return $(a).data('sortby') - $(b).data('sortby');
    });

    u.append(li);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<ul class="filelist">
  <li data-sortby="3">3</li>
  <li data-sortby="2">2</li>
  <li data-sortby="1">1</li>
  <li data-sortby="4">4</li>
</ul>
<ul class="filelist">
  <li data-sortby="5">5</li>
  <li data-sortby="2">2</li>
  <li data-sortby="1">1</li>
  <li data-sortby="4">4</li>
</ul>

I want them show in order like

<ul class="filelist">
  <li data-sortby="1">1</li>
  <li data-sortby="2">2</li>
  <li data-sortby="3">3</li>
  <li data-sortby="4">4</li>
</ul>
<ul class="filelist">
  <li data-sortby="1">1</li>
  <li data-sortby="2">2</li>
  <li data-sortby="4">4</li>
  <li data-sortby="5">5</li>
</ul>

But the error indicated that li.detach is not a function.
Could someone help me solve this problem?
Thanks!

3

Answers


  1. If you want to use jQuery methods like detach, pass the selector to jQuery instead of document.querySelectorAll. In addition, you need to limit the scope of the selection to the current <ul> element rather than the whole document, which can be done by passing the context second argument.

    For example:

    $(function() {
      $('ul.filelist').each((i, el) => {
        $('li', el).detach().sort((a, b) => $(a).data('sortby') - $(b).data('sortby'))
            .appendTo(el);
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul class="filelist">
      <li data-sortby="3">3</li>
      <li data-sortby="2">2</li>
      <li data-sortby="1">1</li>
      <li data-sortby="4">4</li>
    </ul>
    <ul class="filelist">
      <li data-sortby="5">5</li>
      <li data-sortby="2">2</li>
      <li data-sortby="1">1</li>
      <li data-sortby="4">4</li>
    </ul>
    Login or Signup to reply.
  2. Please try using sort method as follows.

    $(document).ready(function() {
      $(".filelist").each(function() {
        const wrapper = $(this);
        wrapper
          .find("li")
          .sort(function(a, b) {
            const aVal = a.dataset.sortby;
            const bVal = b.dataset.sortby;
            return +aVal - +bVal;
          })
          .appendTo(wrapper);
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <ul class="filelist">
         <li data-sortby="3">3</li>
         <li data-sortby="2">2</li>
         <li data-sortby="1">1</li>
         <li data-sortby="4">4</li>
     </ul>
     <ul class="filelist">
         <li data-sortby="5">5</li>
         <li data-sortby="2">2</li>
         <li data-sortby="1">1</li>
         <li data-sortby="4">4</li>
     </ul>
    Login or Signup to reply.
  3. Without JQuery it can be a oneliner. The idea: sort a list of cloned list items of an ul on its data-sortby value, then replace the orgininal items.

    document.querySelectorAll(`ul.filelist`)
      .forEach(ul => {
        const listItems = ul.querySelectorAll(`li[data-sortby]`);
        const sortedList = [...listItems]
          .map(item => item.cloneNode(true))
          .sort( (a, b) => +a.dataset.sortby - +b.dataset.sortby);
        listItems.forEach( (item, i) => item.replaceWith(sortedList[i]) )  
    });
    <ul class="filelist">
         <li data-sortby="3">3</li>
         <li data-sortby="2">2</li>
         <li data-sortby="1">1</li>
         <li data-sortby="4">4</li>
     </ul>
     <ul class="filelist">
         <li data-sortby="5">5</li>
         <li data-sortby="2">2</li>
         <li data-sortby="1">1</li>
         <li data-sortby="4">4</li>
     </ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search