1

I have a user list I'm displaying. My question is, how do I sort them alphabetically but in groups of online statuses.

Basically I want the users that are online to be displayed first, the users that are away second, and the offline users last. Each of those groups I'd like to have sorted alphabetically. My user list looks like this:

<ul>
   <li data-uid="x" data-status="away">John</li>
   <li data-uid="x" data-status="online">Tom</li>
   <li data-uid="x" data-status="online">Mary</li>
   <li data-uid="x" data-status="offline">Xiang</li>
   <li data-uid="x" data-status="away">Chris</li>
   <li data-uid="x" data-status="offline">Peter</li>
   <li data-uid="x" data-status="online">Matt</li>
</ul>

And I'd like them to be sorted like this:

<ul>
   <li data-uid="x" data-status="online">Mary</li>
   <li data-uid="x" data-status="online">Matt</li>
   <li data-uid="x" data-status="online">Tom</li>
   <li data-uid="x" data-status="away">Chris</li>
   <li data-uid="x" data-status="away">John</li>
   <li data-uid="x" data-status="offline">Peter</li>
   <li data-uid="x" data-status="offline">Xiang</li>
</ul>

I've tried using this answer as my starting point, but I just can't manage to get them sorted in groups..

Thanks

Edit:

Also I'm pulling live status updates with ajax. I'm not sure how this could influence the function, but maybe it's possible later on to just target a specific user and move him accordingly?..

Community
  • 1
  • 1
Matt
  • 1,139
  • 1
  • 11
  • 28

4 Answers4

1

Try this jquery code :

var array = ["away", "online", "offline"]

$.each(array, function(key, value) {
    $('li[data-status="'+value+'"]').appendTo('ul')
});

And have a look this fiddle : http://jsfiddle.net/vRz3X/1/

Lucas Willems
  • 6,673
  • 4
  • 28
  • 45
0

code may not be optimised but this works..

    $(function () {
        var mainObj = {};
        var arr = [];
        var status = ["online", 'away', 'offline'];
        $('.a').each(function (i, v) { // a is the class for each li
            if (mainObj[$(this).attr('data-status')] == undefined) {

                mainObj[$(this).attr('data-status')] = [];

            }
            mainObj[$(this).attr('data-status')].push($(this).html());
        })

        var html = '';
        for (var i = 0; i < status.length; i++) {
            mainObj[status[i]].sort();

            for (var j in mainObj[status[i]]) {
                html += '<li class=\"a\" data-status=\"' + status[i] + '\" >' + mainObj[status[i]][j] + '</li>';

            }

        };
        $("#he").append(html); //he is a new ul
    });
lintu
  • 1,092
  • 11
  • 24
0

You can use something like this:

var arrayStatus = ["away", "online", "offline"];

$("#sorter").click(function () {
    var sortedList = $('ul li').sort(function (a, b) {
        var chA = $(a).data('status');
        var chB = $(b).data('status');        
        if (arrayStatus.indexOf(chA) < arrayStatus.indexOf(chB)) return -1;
        if (arrayStatus.indexOf(chA) > arrayStatus.indexOf(chB)) return 1;
        return 0;
    }).sort(function (a, b) {
        var chA = $(a).data('status');
        var chB = $(b).data('status');        
        if (chA == chB){
            if ($(a).text()< $(b).text()) return -1;
            if ($(a).text()> $(b).text()) return 1;
        }
        return 0;
    });
    $('ul').empty();    
    $('ul').append(sortedList);
});

It can't be the faster ever because the use of the sort function on arrays; but it works pretty well.

Working fiddle: http://jsfiddle.net/IrvinDominin/seEMJ/

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
0

I managed to take bits out of each answer, combine it with other answers here on StackOverflow, and this is what I came up with:

// instead of creating on the fly like lintu, I make the arrays beforehand
var tempSort = {online:[],away:[],offline:[]};

$('li').each(function() {
    // insert array [uid, name] into corresponding status array
    tempSort[$(this).attr('data-status')].push([$(this).attr('data-uid'), $(this).text()]);
});

// sort each status block by name (second multidimensional array item)
for(var status in tempSort) {
    tempSort[status].sort(function(a, b) { if (a[1]<b[1]) return -1; if (a[1]>b[1]) return 1; return 0; });
}

After this sort I'm left with a sorted array, which I just iterate and move users accordingly in the <ul>.

Matt
  • 1,139
  • 1
  • 11
  • 28