6

The network accounts list (at http://stackexchange.com/users/<USER_ID>/?tab=accounts) is generally sorted by reputation.

How can I sort it by another criteria? eg. when I last visited a site, the number of questions I've asked, etc.

  • 1
    Related feature request. (Ideally, each user will be able to decide how his/her own accounts will appear to others, and that will be done via the network profile.) – ShaWiz May 20 '16 at 6:06
  • 1
    Thanks for the heads up @ShadowWizard. I posted this on there too. Agree it is ideal to be implemented network wide. – Tim Malone May 20 '16 at 6:15
6

This sorting doesn't appear to be integrated by default. However, it's fairly easy to integrate with a custom script.

I've written the below which should do a fairly good job of offering basic sorting options. It's not perfect - especially because there's only so much you can sort dates like '2 years ago'!) but I think it works pretty well.

It will add a sorting bar to the page that looks like this:

enter image description here

To install, create a bookmark (eg. on your browser's bookmarks bar), copy the entire code below, and paste it into the address of the bookmark. Open your network accounts list, and click the bookmarklet!

javascript:
jQuery(".account-container").each(function(){

    dates = jQuery(this).find(".cool:contains(Joined)").text().replace("Joined ", "").replace("last seen ", "").split(", ");
    dates_processed = new Array();

    for(i = 0; i <= 1; i++){

        dates_processed[i] = new Date();

        if(dates[i].indexOf("today") !== -1){
            /* nothing to do, it's today! */
        }else if(dates[i].indexOf("yesterday") !== -1){
            dates_processed[i].setDate(dates_processed[i].getDate() - 1);
        }else if(dates[i].indexOf(" day ago") !== -1 || dates[i].indexOf(" days ago") !== -1){
            dates[i] = dates[i].replace(" day ago", "").replace(" days ago", "");
            dates_processed[i].setDate(dates_processed[i].getDate() - (dates[i] * 1));
        }else if(dates[i].indexOf(" month ago") !== -1 || dates[i].indexOf(" months ago") !== -1){
            dates[i] = dates[i].replace(" month ago", "").replace(" months ago", "");
            dates_processed[i].setDate(dates_processed[i].getDate() - (dates[i] * 31));
        }else if(dates[i].indexOf(" year ago") !== -1 || dates[i].indexOf(" years ago") !== -1){
            dates[i] = dates[i].replace(" year ago", "").replace(" years ago", "");
            dates_processed[i].setDate(dates_processed[i].getDate() - (dates[i] * 366));
        }

    }

    jQuery(this).attr("data-name", jQuery(this).find(".account-site a").text().trim());
    jQuery(this).attr("data-joined", dates_processed[0].getTime());
    jQuery(this).attr("data-last-seen", dates_processed[1].getTime());
    jQuery(this).attr("data-reputation", jQuery(this).find(".cool:contains(reputation)").prev().text());
    jQuery(this).attr("data-gold-badges", jQuery(this).find(".badge1").next().text());
    jQuery(this).attr("data-silver-badges", jQuery(this).find(".badge2").next().text());
    jQuery(this).attr("data-bronze-badges", jQuery(this).find(".badge3").next().text());
    jQuery(this).attr("data-questions", jQuery(this).find(".cool:contains(questions)").prev().text());
    jQuery(this).attr("data-answers", jQuery(this).find(".cool:contains(answers)").prev().text());

});

/* add the sorter div, after removing any that is there already, in case we're running this more than once */

    jQuery(".vcard .sorter").remove();

    jQuery(".vcard").append('\
        <div class="sorter" style="float: left; margin: 1em 0; font-size: .85em;">\
            Sort by: <a data-type="string">name</a> | <a data-type="timestamp">joined</a> | <a data-type="timestamp">last seen</a> | <a>reputation</a> | <a>gold badges</a> | <a>silver badges</a> | <a>bronze badges</a> | <a>questions</a> | <a>answers</a>\
        </div>\
    ');

/* make the update profile info link align with our new sorter */

    jQuery(".default-profile-site").css("margin-top", "1em");

jQuery(".vcard .sorter a").on("click", function(event){

    event.preventDefault();

    jQuery(this)
        .siblings("a") /* return other links to normal state */
            .css("color", "#366FB3")
            .css("font-weight", "normal")
        .end() /* set the clicked link to an active state */
            .css("color", "black")
            .css("font-weight", "bold")
    ;

    attribute_type = "integer"; /* default attribute type */
    if(jQuery(this).attr("data-type")){ attribute_type = jQuery(this).attr("data-type"); }
    account_sorter("data-" + jQuery(this).text().replace(" ", "-"), attribute_type);

});

function account_sorter(attribute_name, attribute_type){

    accounts = jQuery(".account-container");

    accounts.sort(function(account1, account2){

        if(attribute_type == "integer" || attribute_type == "timestamp"){
            attribute1 = parseInt(jQuery(account1).attr(attribute_name).replace(/[^0-9]/g, ""));
            attribute2 = parseInt(jQuery(account2).attr(attribute_name).replace(/[^0-9]/g, ""));
            if(isNaN(attribute1)){ attribute1 = -1; }
            if(isNaN(attribute2)){ attribute2 = -1; }
        }

        if(attribute_type == "string" || attribute_type == "timestamp"){
            /* intentionally reverse these so the sorting happens smallest to largest */
            attribute1 = jQuery(account2).attr(attribute_name);
            attribute2 = jQuery(account1).attr(attribute_name);
        }

        if(attribute1 < attribute2){
            return 1;
        }else{
            return -1;
        }
        return 0;

    });

    accounts.detach().appendTo("#content > .contentWrapper");

}

/* set your default sort here */

    jQuery(".vcard .sorter a:contains(answers)").trigger("click");

Happy for any suggestions, improvements or bug fixes - feel free to edit the post directly if you're sure what you're changing works.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .