Slowboy
Slowboy

Reputation: 601

How do I sort list items based on numbers at the end of text inside?

I've combined two items ( the name and the year) from JSON data to appear like this by using Jquery. My problem is if I can sort this <ul> by the number at the end of each line in the first <a>.

<ul id="job">
<li> 
  <a href="#"> Name1 (2001)</a>
   <br>
  <a href="#"> link to Name1 related stuff</a>
</li>
<li> 
  <a href="#"> Name2 (1994)</a>
   <br>
  <a href="#"> link to Name2 related stuff</a>
</li>
   <li> 
  <a href="#"> Name3 (2005)</a>
   <br>
  <a href="#"> link to Name3 related stuff</a>
</li>
</ul>

I've been using this code block below on other occasions in this project but I'm not sure how I can modify it to sort by the number at the end as I would like to.

 function sortResults(selector){
   var $ul= $(selector);
   $ul.find('li').sort(function (a,b) {
   var upA = $(a).text().toUpperCase();
   var upB = $(b).text().toUpperCase();
   return (upA < upB) ? -1 : (upA > upB) ? 1 : 0;
}).appendTo(selector);
};

can anyone advise on this?

Upvotes: 1

Views: 129

Answers (1)

palaѕн
palaѕн

Reputation: 73906

Few things here:

  1. $(a).text() return the full text inside all htmls inside li. You will just need to use $(a).find('a:first').text(). To get the first link text inside li.
  2. After that, you will need to get the text between (xxx) and convert that to a number like:

    var upA = +$(a).find('a:first').text().match(/\((.*?)\)/)[1];
    var upB = +$(b).find('a:first').text().match(/\((.*?)\)/)[1];
    
  3. Then do a simple number sorting like return upB - upA;

  4. And finally, get the sorted list items and append the new list to the ul again to update the UI as well.

Demo:

var $ul = $('ul');
var items = $ul.children('li').get();

items.sort(function(a, b) {
  var upA = +$(a).find('a:first').text().match(/\((.*?)\)/)[1];
  var upB = +$(b).find('a:first').text().match(/\((.*?)\)/)[1];
  return upB - upA;
})

$.each(items, function(_, li) {
  $ul.append(li);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="job">
  <li>
    <a href="#"> Name1 (2001)</a>
    <br>
    <a href="#"> link to Name1 related stuff</a>
  </li>
  <li>
    <a href="#"> Name2 (1994)</a>
    <br>
    <a href="#"> link to Name2 related stuff</a>
  </li>
  <li>
    <a href="#"> Name3 (2005)</a>
    <br>
    <a href="#"> link to Name3 related stuff</a>
  </li>
</ul>

Upvotes: 2

Related Questions