47

I have an HTML structure as follows:

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

I would like to sort them as:

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

I am using the following function:

function sortContacts() {
    var contacts = $('div.clist'), cont = contacts.children('div');

    cont.detach().sort(function(a, b) {
        var astts = $(a).data('sid');
        var bstts = $(b).data('sid')
        return (astts > bstts) ? (astts > bstts) ? 1 : 0 : -1;
    });

    contacts.append(cont);
}

It is not working as expected.

It is working well for the first run but after adding new element or changing the data-sid attributes it no longer works.

Demo: http://jsfiddle.net/f5mC9/1/

Not working?

2
  • i would like to swap elements Commented Nov 21, 2012 at 9:51
  • you could use tinysort (tinysort.sjeiti.com) Commented Nov 21, 2012 at 10:14

4 Answers 4

81

You can use dataset property which stores all of the custom data-* attributes of an element, it returns a string, in case that you want to convert the string to a number you can use parseInt or + operator.

$('.clist div').sort(function(a,b) {
     return a.dataset.sid > b.dataset.sid;
}).appendTo('.clist');

http://jsfiddle.net/CFYnE/

And your own code also work: http://jsfiddle.net/f5mC9/

Edit: Please note that IE10! and below do not support the .dataset property, if you want to support all browsers you can use jQuery's .data() method instead:

$('.clist div').sort(function(a,b) {
     return $(a).data('sid') > $(b).data('sid');
}).appendTo('.clist');
Sign up to request clarification or add additional context in comments.

7 Comments

Note that using .data() to access HTML data attributes creates a copy of the data attribute when it is first accessed. If you change the data attribute's value later on, data() will still return the old value.
I'm not getting .data() to work in IE11 or Edge. :( jsfiddle.net/4o771n7o
@jimmykup - .data() works just fine in IE11 and Edge. It is the comparison which is different.
I ran into problems when sorting a list of more than 10 by a string value. I had to change the comparison to: return a.dataset.sid > b.dataset.sid ? 1 : (a.dataset.sid < b.dataset.sid ? -1 : 0);
@trincot That's a good point. It should be noted that jQuery .data() tries to parse the data-* attributes as JSON, so stringified numbers are coerced into real numbers by jQuery.
|
15
$('.clist div').sort(function(a,b) {
     return parseInt(a.dataset.sid) - parseInt(b.dataset.sid);
}).appendTo('.clist');

1 Comment

How to reverse the sort so that it's descending?
6

A more generic function to sort elements using jQuery:

$.fn.sortChildren = function (sortingFunction: any) {

    return this.each(function () {
        const children = $(this).children().get();
        children.sort(sortingFunction);
        $(this).append(children);
    });

};

Usage:

$(".clist").sortChildren((a, b) => a.dataset.sid > b.dataset.sid ? 1 : -1);

Comments

0

function orderSteps() {
    var steps = $('div.steps'),
        cont = steps.children('div.step');
    cont.detach().sort(function (a, b) {
        var astts = a;
        var bstts = b;

        // stripping the id to get the position number
        var classArrA = $(astts).attr("id").split("-")[1];
        var classArrB = $(bstts).attr("id").split("-")[1];

        // checking for the greater position and order accordingly
        if (parseInt(classArrA) > parseInt(classArrB)) {
            return (0)
        }
        else {
            return (-1)
        }
    })
    steps.append(cont);
};

orderSteps()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid steps">
            <div class="row text-center border-bottom step" id="step-1">
                <span class="col-3">Item 1</span>
            </div>
            <div class="row text-center border-bottom step" id="step-2">
                <span class="col-3">Item 2</span>
            </div>
            <div class="row text-center border-bottom step" id="step-30">
                <span class="col-3">Item 3</span>
            </div>
            <div class="row text-center border-bottom step" id="step-4">
                <span class="col-3">Item 4</span>
            </div>
        </div>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.