4

I need to sort some elements depend on it attribute. For an example:

<div id="sort">
<div n="1"></div>
<div n="2"></div>
<div n="3"></div>
<div n="4"></div>
</div>

And array_num

{3, 2, 1, 4}

pseudo code:

$('#sort').sort(array_num, 'n');

results will be:

<div id="sort">
<div n="3"></div>
<div n="2"></div>
<div n="1"></div>
<div n="4"></div>
</div>
7
  • Is there some kind of logic behind that order or do you need it just exactly like that? Commented Aug 25, 2010 at 6:37
  • n is not a valid html tag attribute. It will cause you some undesired behavior on some browser. Commented Aug 25, 2010 at 6:38
  • @jAndy: I want exactly like that :D @Reigel: jquery have expando attribute itself. Commented Aug 25, 2010 at 6:38
  • yes, but that above is html and not jQuery :) Commented Aug 25, 2010 at 6:42
  • If you use jquery in IE, try to see innerHTML you will see expando attribute of Jquery in html tag ex: <div JQuery3312312313="12"></div>. Commented Aug 25, 2010 at 6:48

4 Answers 4

8
​var order = [3, 2, 4, 1]​;
var el = $('#sort');
var map = {};

$('#sort div').each(function() { 
    var el = $(this);
    map[el.attr('n')] = el;
});

for (var i = 0, l = order.length; i < l; i ++) {
    if (map[order[i]]) {
        el.append(map[order[i]]);
    }
}

Full code here

Sign up to request clarification or add additional context in comments.

1 Comment

Works excellently, even if an element in the $.each() is missing its attribute - just puts the element at the top. And it works when numbers in the var order are missing from the set of matched elements too.
5

untested...

$.fn.asort = function (order, attrName) {
    for(var i = 0, len = order.length; i < len; ++i) {
        this.children('[' + attrName + '=' + order[i] + ']').appendTo(this);
    }
}

Comments

0

I stumbled across this trying to fix what I was after. I took @shrikant-sharat's method and added a little to it as the attribute I needed to sort on was actually on a child element. Thought I'd add here in case it helps anyone (and for future me!)

$.fn.asort = function (order, attrName, filter) {
  console.log(this.length, order.length, order);
  for(var i = 0, len = order.length; i < len; ++i) {

    if(typeof(filter) === 'function') {
      filter(this.children(), attrName, order[i]).appendTo(this);
    } else {
      this.children('[' + attrName + '=' + order[i] + ']').appendTo(this);
    }
  }
  return this.children();
}

It allows you to pass a filter function to match the element you're after. It's not the most efficient I suppose, but it works for me, e.g.:

$('.my-list').asort(mapViewOrder, 'data-nid', function(items, attrName, val) {
  return items.filter(function(index, i) {
    return ($(i).find('[' + attrName + '="' + val + '"]').length);
  });
});

Comments

0

Since jQuery returns an array of objects, you may use the sort method, and then 'reappend' the children to the parent in the newly sorted order:

var order = [3, 2, 1, 4];

var div = $('#sort');

div.children().sort((a, b) => {
  var aIndex = order.indexOf(parseInt(a.getAttribute('n')));
  var bIndex = order.indexOf(parseInt(b.getAttribute('n')));

  return aIndex - bIndex;
}).appendTo(div);
#sort > div {
  padding: 10px;
  border-bottom: 1px solid #E1E1E1;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sort">
  <div n="1">1</div>
  <div n="2">2</div>
  <div n="3">3</div>
  <div n="4">4</div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.