0

This function seems to work fairly well for sorting divs based on ID:

JS

var div = $("<div id='3.5'>AA</div>");
div_id_after = Math.floor(parseFloat(div.get(0).id));

$('#'+div_id_after).after(div);

HTML

<div id='1'>a</div>
<div id='2'>b</div>
<div id='3'>c</div>
<div id='4'>d</div>
<div id='5'>e</div>

Produces:

a
b
c
AA
d
e

But what if I would like to use a custom attribute titled "order"?

The ID should not be a number for compatibility issues, but does this same rule apply to custom attributes?

TaylorMac
  • 8,882
  • 21
  • 76
  • 104

2 Answers2

13

If you're trying to sort on a custom data attribute, here's what I've done in the past:

html:

<ul class="sortList">
    <li data-sort="1">I am number one</li>
    <li data-sort="7">I am number seven</li>
    <li data-sort="22">I am number twenty two</li>
    <li data-sort="2">I am number two</li>
</ul>

Because the list isn't in order and it's not sequential, the easiest way to do the sort is to use javascript's sort method on a jQuery selected array:

javascript:

var list = $('.sortList');
var listItems = list.find('li').sort(function(a,b){ return $(a).attr('data-sort') - $(b).attr('data-sort'); });
list.find('li').remove();
list.append(listItems);

Because jQuery returns an array of elements, the native sort method will give you a sorted array of selectors that you can just replace the contents of the list with.

After the sort, your list will look like this:

<ul class="sortList">
    <li data-sort="1">I am number one</li>
    <li data-sort="2">I am number two</li>
    <li data-sort="7">I am number seven</li>
    <li data-sort="22">I am number twenty two</li>
</ul>

One thing to note as well: I use data-sort as the attribute, because attributes that start with "data-" are treated differently by browsers, so this won't cause validation issues.

/////// EDIT:

Given your comment, here's another way to do it without replacing the entire array. This will almost certainly be slower and require refining, I would still recommend using the above solution, but if you wanted to append without modifying the list:

//// This would happen inside a function somewhere
var list = $('ul li');
var newItem = $('<li data-sort="7"></li>'); // I assume you will be getting this from somewhere
$.each(list,function(index,item){
    var prev = parseFloat($(item).attr('data-sort'));
    var next = parseFloat($(list[index+1]).attr('data-sort'));
    var current = parseFloat(newItem.attr('data-sort'));
    if(prev <= current && (next > current || isNaN(next)) ){
        $(item).after(newItem);
    } else if(current > prev){
        $(item).before(newItem);
    }
});
Jesse
  • 10,370
  • 10
  • 62
  • 81
  • this seems to work well. If you append an object to .sortList before the sort function is called it will sort that object too. If you create an object with a click event after the function is called, you would need to run this function again to resort. I am looking for something that will not need to create an array every time a new object is introduced – TaylorMac May 20 '11 at 19:57
  • I added another solution to my answer, but to be honest I can't think of a use case where sort() wouldn't be the fastest/cleanest solution to your problem. You can run it as many times as you want, and it won't mess with anything on or around your elements. – Jesse May 20 '11 at 20:38
3

It looks like TinySort will do what you want.

$("ul").tsort({attr:"order"});

Also of interest after a quick google search is another SO Question.

Community
  • 1
  • 1
Mike
  • 3,219
  • 23
  • 29
  • 1
    I'm sure it's a matter of preference, but I personally wouldn't use a plugin for this - jQuery returns an array, which is great for sorting. Keep your javascript light, and avoid plugins unless absolutely necessary. That said, do what you want unless I have to maintain your code later. – Jesse May 20 '11 at 19:52
  • I am really looking for something where dynamically created objects will be appended (after or before, either way) in the correct location – TaylorMac May 20 '11 at 20:00
  • 3
    @Jesse, I generally agree that plugin hell is something to avoid, but in this case the plugin is rather small and the code is an exceedingly easy to read single line, so it seemed an apt use of KISS and DRY methodologies. But by all means TaylorMac, do what you feel is right for your code. – Mike May 21 '11 at 01:21