0

I'd like to sort a list with links alphabetical this is my code:

!DOCTYPE html>
<html>
<head>
    <title>Sort list items alphabetically with Javascript</title>
    <script type="text/javascript">

    function sortUnorderedList(ul, sortDescending) {
      if(typeof ul == "string")
        ul = document.getElementById(ul);

      var lis = ul.getElementsByTagName("LI");
      var vals = [];

      for(var i = 0, l = lis.length; i < l; i++)
        vals.push(lis[i].innerHTML);

      vals.sort();

      if(sortDescending)
        vals.reverse();

      for(var i = 0, l = lis.length; i < l; i++)
        lis[i].innerHTML = vals[i];
    }

    window.onload = function() {
      var desc = false;
      document.getElementById("test").onclick = function() {
        sortUnorderedList("list", desc);
        desc = !desc;
        return false;
      }
    }

    </script>
</head>
<body>
    <div id="test"> <a href="#">Sort List</a></div>
    <ul id="list">
        <li>Peter</li>
        <li>Mary</li>
        <li>Paul</li>
        <li>Allen</li>
        <li>James</li>
        <li>Vicki</li>
        <li>Brock</li>
        <li>Dana</li>
        <li>Frank</li>
        <li>Gil</li>
        <li>Helen</li>
    </ul>
</body>

But when i want to add links to the names, the list gets all messed up (not alphabetical anymore), so what should i change? I have absolutely no knowledge about javascript, could someone help me out here, thank you

<div id="test"> <a href="#">Sort List</a></div>
    <ul id="list">
        <li><a href="tumblr.com/post/57781372261">Peter</a></li>
        <li><a href="tumblr.com/post/57783141055">Mary</a></li>
        <li><a href="tumblr.com/post/57781372261">Paul</a></li>
     </ul>

when the links are added, the posts will be sorted by the numbers there, and not by the names..

M'''
  • 51
  • 2
  • 11
  • `ul` stands for "unsorted list" – Sebas Aug 13 '13 at 16:53
  • Fixed the title/tags for you. [Java is not JavaScript](http://stackoverflow.com/questions/245062/whats-the-difference-between-javascript-and-java) (scroll down for the more serious answers) – DannyMo Aug 13 '13 at 16:53
  • Could you post the version with the links added? It's hard to tell what's wrong when you don't post the version that exhibits the problem. – Barmar Aug 13 '13 at 16:58

1 Answers1

3

You're sorting by whatever is between <li> and </li>, which includes the URLs, not just the names. So if the URLs don't sort similarly to the names, the results will be out of order. In your case, you're sorting by the ID numbers in the URLs.

A simple way to solve this is to put the names in the anchor elements, e.g.

    <li><a data-name="Peter" href="tumblr.com/post/57781372261">Peter</a></li>
    <li><a data-name="Mary" href="tumblr.com/post/57783141055">Mary</a></li>
    <li><a data-name="Paul" href="tumblr.com/post/57781372261">Paul</a></li>

Putting the data-name attribute before the href attribute should make it take precedence.

Actually, I'm not totally sure this will work. The innerHTML property contains the HTML after it's been parsed by the browser, and it's possible it reorders attributes. To really solve this, you need to provide a comparison function to sort() that finds the names and compares them, rather than comparing the HTML directly.

Here's a version that compares the text only. It works with the DOM nodes themselves, rather than converting to and from HTML.

function compareText(a1, a2) {
    var t1 = a1.innerText, t2 = a2.innerText;
    return t1 > t2 ? 1 : (t1 < t2 ? -1 : 0);
}

function sortUnorderedList(ul, sortDescending) {
  if(typeof ul == "string") {
    ul = document.getElementById(ul);
  }

  var lis = ul.getElementsByTagName("LI");
  var vals = [];

  for(var i = 0, l = lis.length; i < l; i++) {
    vals.push(lis[i]);
  }

  vals.sort(compareText);

  if(sortDescending) {
    vals.reverse();
  }

  ul.innerHTML = '';
  for(var i = 0, l = vals.length; i < l; i++) {
    ul.appendChild(vals[i]);
  }
}

DEMO

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • it's not working :(( , i've added the data-names to my links, but after i save it, tumblr put those 'data-names' after the 'href="URL" .. so what now? – M''' Aug 13 '13 at 17:33
  • Tumblr didn't do it, the browser did, like I said it might. – Barmar Aug 13 '13 at 18:49
  • I've added a new version of `sortUnorderedList` that solves the problem. – Barmar Aug 13 '13 at 19:05