3

I used this question (jQuery sort elements using data id) to get a lot of work done on a project I'm doing.

The top voted answer mentions that using jQuery;s .data() is required if I need it to work in IE10 and below. I haven't tested it in any of those browsers, but I have found that it does not work in IE11 or Edge.

Here's the jsfiddle that works just fine in Chrome for me: http://jsfiddle.net/4o771n7o/

HTML

<div class="clist">
    <div data-sid=1>1</div>
    <div data-sid=4>4</div>
    <div data-sid=3>3</div>
    <div data-sid=1>1</div>
    <div data-sid=4>4</div>
    <div data-sid=2>2</div>
    <div data-sid=1>1</div>
</div>

Javascript

$('.clist div').sort(function(a,b) {
     return $(a).data('sid') > $(b).data('sid');
}).appendTo('.clist');
Community
  • 1
  • 1
jkupczak
  • 2,891
  • 8
  • 33
  • 55

3 Answers3

4

The sort function is bad; I'm not sure why it works for any other browser. Working JSFiddle:

http://jsfiddle.net/0m75k1fm/

The sort function should return a number, not a boolean:

$('.clist div').sort(function(a,b) {
     return parseInt($(a).data('sid'), 10) - parseInt($(b).data('sid'), 10);
}).appendTo('.clist');
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • Looks like IE can handle the missing quotes; it's just the sort function that is specifically tripping it up. – Jacob Dec 07 '15 at 21:19
  • 1
    Basically you didn't change anything. Quotes are optional in this case and `>` handles to number conversion behind the scene. – dfsq Dec 07 '15 at 21:19
  • The attributes are not malformed. Yes, changing it to subtract does help because the compareFunction expects an integer but it doesn't really answer the question. – Travis J Dec 07 '15 at 21:19
  • @dfsq: look carefully. – Jacob Dec 07 '15 at 21:19
  • @TravisJ, it does answer the question; the sort function is completely wrong. – Jacob Dec 07 '15 at 21:20
  • See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort for an explanation of sort functions. – Jacob Dec 07 '15 at 21:21
  • @Jacob - While the sort function is not directly returning the proper type, it has worked for a long time in this fashion. Perhaps if you got into why using the logical comparison is no longer working in this exact browser you would be getting closer. – Travis J Dec 07 '15 at 21:22
  • 1
    @dfsq: Sort functions should return -1, 0, or 1 to indicate ordering. Just because JS can convert Boolean to Number doesn't mean the sort function is correct. – Jacob Dec 07 '15 at 21:22
  • Yes, I agree about sorting returning number. Then `return $(a).data('sid') - $(b).data('sid');` should be enough. Anyway +1 for this, this might be the issue for IE. – dfsq Dec 07 '15 at 21:24
  • Perhaps some browsers happen to succeed due to their specific sorting algorithm, but they're not _supposed_ to work with a sort function like that. – Jacob Dec 07 '15 at 21:25
  • Thanks for this. Evgeny's answer worked for me as well. Marked this one as correct since the discussion in the comments gave me a good understanding of what was going on. – jkupczak Dec 07 '15 at 21:35
  • @dfsq - It is most certainly the issue for newer versions of IE. It would have been nice to see an explanation of *why* here though aside from just "do this" which is basically what is shown. There is no explanation given. – Travis J Dec 07 '15 at 21:43
2

You can use

$('.clist div').sort(function(a,b) {
     return $(a).attr('data-sid') > $(b).attr('data-sid') ? 1 : -1;
}).appendTo('.clist');

Works in edge

Evgeny
  • 113
  • 1
  • 7
0

You can sort HTML elements pretty easily without jQuery. Just use the built in document.querySelectorAll function to select your collection of HTML elements (as a nodelist) and then use the built in Array.prototype.sort.apply(YourCollection,[SortFunction]) to invoke the Array object's sort function on your nodeList.

var nodes = document.querySelectorAll(".clist [data-sid]");

Array.prototype.sort.apply(nodes,
[function(first, second) {
    var a = +first.getAttribute("data-sid"),
      b = +second.getAttribute("data-sid");
    return a > b ? 1 : (a < b ? -1 : 0);
  }]);

for (i = 0, len = nodes.length; i < len; i++) {
  document.querySelector(".clist").appendChild(nodes[i]);
}
[data-sid] {
  border: 1px solid black;
}
[data-sid="1"] {
  background-color: rgb(255, 250, 250);
}
[data-sid="2"] {
  background-color: rgb(255, 200, 200);
}
[data-sid="3"] {
  background-color: rgb(255, 100, 100);
}
[data-sid="4"] {
  background-color: rgb(255, 50, 50);
}
<div class="clist">
  <div data-sid=1>1</div>
  <div data-sid=4>4</div>
  <div data-sid=3>3</div>
  <div data-sid=1>1</div>
  <div data-sid=4>4</div>
  <div data-sid=2>2</div>
  <div data-sid=1>1</div>
</div>
Thriggle
  • 7,009
  • 2
  • 26
  • 37