3

I'm populating a few drop downs from some JSON, it works as expected at the moment but i'm trying to sort the values in the drop downs. For all my drop downs it works fine, except for one of them which has numbers in, in which case it lists it 1, 10, 12, 2.

Any ideas how i can keep it sorting alphabetically for everything else but get the sort to work with the numeric values too?

Here's my JS (this replicates for each field - probably should try to find a way to make this reuseable):

var populateGenres = _.map(data.genres, function (val) {
    return '<option>' + val + '</option>';
}).join();
 var target = '#genreField';
$('#genreField').html(populateGenres);
reArrangeSelect(target);

Here's the sort JS:

function reArrangeSelect(target) {
    $(target).html($(target + " option").sort(function(a, b) {
        return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
    }))
}

My HTML is in this format:

<td>
    <select id="genreField" class="form-control"></select>
</td>
<td>
    <select id="authorField" class="form-control"></select>
</td>
chridam
  • 100,957
  • 23
  • 236
  • 235
Hagbard
  • 575
  • 5
  • 8
  • 18
  • Does this help? "Sort numbers with letters numerically and alphabetically" http://stackoverflow.com/questions/17996193/sort-numbers-with-letters-numerically-and-alphabetically – bloodyKnuckles Jun 20 '14 at 11:43
  • Here for your drop down sort the numbers 1, 10, 12, 2 is sounds like string not integer. Check all numbers are integer??? – Shail Jun 20 '14 at 11:43
  • If the JSON is generated on server side, I'd rather invest time on server-side sorting, either during the data retrieval itself or before serializing the JSON. Client-side approach isn't very reliable, not mentioning the fact that it would cause page freezes on slower computers or when using larger collections. – JKurcik Jun 20 '14 at 11:45
  • Hi, thanks for the suggestion, the data is server side but its not an option to do it there for various reasons. Despite getting 'long running script errors' on IE8 – Hagbard Jun 20 '14 at 11:53
  • And yes the all data (including numbers) are returned as a string – Hagbard Jun 20 '14 at 11:56

2 Answers2

1

You can sort data.genres before running it through the _.map functions:

data.genres.sort(function (a, b) {
    a = parseInt(a, 10);
    b = parseInt(b, 10);
    if(a > b) {
        return 1;
    } else if(a < b) {
        return -1;
    } else {
        return 0;
    }
});

Once you sort the data then run your _.map snippet:

var populateGenres = _.map(data.genres, function (val) {
    return '<option>' + val + '</option>';
}).join();

All of your options should now be sorted before you append them to the <select>.

DEMO

War10ck
  • 12,387
  • 7
  • 41
  • 54
  • Thats for this, is there a way of making it more reuseable though, i have 10 drop downs i'm trying to sort so would prefer not to replicate the sort for each of the data.genre, data.author etc.? – Hagbard Jun 20 '14 at 11:55
  • Do all ten drop downs contain integers? – War10ck Jun 20 '14 at 11:55
  • No, all the data is in string format when it comes back from the server. Some drop downs are alphabetic (like Author) some are wholly numeric. – Hagbard Jun 20 '14 at 11:57
1
function reArrangeSelect(target) {
  $(target).html($(target + " option").sort(function(a, b) {
    // u can use that 'getValue' function
    // for "a.text == 'some string'" it will return 'some string' (string type), 
    // for "a.text == '10'" it will return 10 (number type)
    var aVal = getValue(a.text);
    var bVal = getValue(b.text);
    return aVal == bVal ? 0 : aVal < bVal ? -1 : 1;
  }));
}

function getValue(val) {
 var asNumber = parseFloat(val);
 return isNaN(asNumber) ? val : asNumber;
}
Eru Iluvatar
  • 101
  • 3