17

I am looking for a function that will take a list of options in a select list and sort them alphabetically but with a twist. All values with the text 'NA' should be pushed to the bottom of the list.

So given a list -

<select>
    <option value="1">Car</option>
    <option value="2">Bus</option>
    <option value="3">NA</option>
    <option value="4">Bike</option>
    <option value="5">Tractor</option>
    <option value="6">NA</option>
</select>

We should end up with -

<select>
    <option value="4">Bike</option>
    <option value="2">Bus</option>
    <option value="1">Car</option>
    <option value="5">Tractor</option>
    <option value="3">NA</option>
    <option value="6">NA</option>
</select>

The order of the NAs is not important.

And don't ask why I cannot just remove the NAs (or why there will be several options with the same texts but different underlying values, because I don't agree with it either.

glosrob
  • 6,631
  • 4
  • 43
  • 73
  • Worth noting for all these answers: sorting will change which option is selected. You must persist the value of the select element before the sort and restore it afterwards. – Steve Clay Nov 25 '14 at 16:42

4 Answers4

45

demo: http://jsfiddle.net/4bvVz/

function NASort(a, b) {    
    if (a.innerHTML == 'NA') {
        return 1;   
    }
    else if (b.innerHTML == 'NA') {
        return -1;   
    }       
    return (a.innerHTML > b.innerHTML) ? 1 : -1;
};

$('select option').sort(NASort).appendTo('select');
kei
  • 20,157
  • 2
  • 35
  • 62
16
var sb = $('select');

sb.append(sb.find('option').sort(function(a, b){
    return (
        a = $(a).text(),
        b = $(b).text(),
        a == 'NA' ? 1 : b == 'NA' ? -1 : 0|a > b
    );
}));
1

If you have more than one select in the page (multiple selects) use this:

function NASort(a, b) {
    if (a.innerHTML == 'NA') {
        return 1;
    }
    else if (b.innerHTML == 'NA') {
        return -1;
    }
    return (a.innerHTML > b.innerHTML) ? 1 : -1;
};

$('select').each(function( index ) {
    $(this).find('option').sort(NASort).appendTo($(this));
});
Francisco Costa
  • 6,713
  • 5
  • 34
  • 43
1

I've made ​​some changes to the original function and it worked fine.

function NASort(a, b) {  
    console.log(a.innerHTML.substr(0, 1).toLowerCase() + ' > ' + b.innerHTML.substr(0, 1).toLowerCase());
    return (a.innerHTML.substr(0, 1).toLowerCase() > b.innerHTML.substr(0, 1).toLowerCase()) ? 1 : -1;
};

$('select option').sort(NASort).appendTo('select');
Luís Cruz
  • 14,780
  • 16
  • 68
  • 100