I have jQuery but I'm not sure if it has any built-in sorting helpers. I could make a 2d array of each item's text
, value
, and selected
properties, but I don't think that javascript's built in Array.sort()
would work correctly.

- 35,751
- 21
- 71
- 94
-
4Note to self (since I've come back to this question multiple times via google): here's a good solution that you wrote: https://gist.github.com/1072537 – travis Jul 08 '11 at 20:23
12 Answers
Extract options into a temporary array, sort, then rebuild the list:
var my_options = $("#my_select option");
var selected = $("#my_select").val();
my_options.sort(function(a,b) {
if (a.text > b.text) return 1;
if (a.text < b.text) return -1;
return 0
})
$("#my_select").empty().append( my_options );
$("#my_select").val(selected);
Mozilla's sort documentation (specifically the compareFunction) and Wikipedia's Sorting Algorithm page are relevant.
If you want to make the sort case insensitive, replace text
with text.toLowerCase()
The sort function shown above illustrates how to sort. Sorting non-english languages accurately can be complex (see the unicode collation algorithm). Using localeCompare in the sort function is a good solution, eg:
my_options.sort(function(a,b) {
return a.text.localeCompare(b.text);
});

- 6,731
- 1
- 40
- 38
-
1revisiting this question 3 years later, and this route seems like the right way to go – travis Jul 08 '11 at 17:47
-
8Note that this is case-sensitive -- that is, it will sort all things that start with uppercase letters before things that start with lowercase letters. If this is undesirable, just add a `.toUpperCase()` after each `.text` – TJ Ellis Dec 02 '11 at 17:49
-
10Also it will not preserve the currently-selected option in all browsers as-is (Chrome remembered what was selected, but firefox and ie didn't, and selected the last element after options were readded). To fix this, save the current selected value before sorting, then reselect it. i.e., before anything else do `var selected = $("#my_select").val();` and then after the sorted options have been appended, restore the val, i.e. `$("#my_select").val(selected);` – TJ Ellis Dec 02 '11 at 17:52
-
3
-
@TJEllis regarding the case-sensitivity, this question provides even more info why one should use `.toUpperCase()` vs `.toLowerCase()` when ignoring cases http://stackoverflow.com/questions/2140627/javascript-case-insensitive-string-comparison – Adriano Sep 26 '14 at 09:28
-
@TJEllis you are discussing the `Natural Sort Algorithm`, which is actually the very interesting/difficult part of the question (i18n might be a major challenge). Read more about this on http://stackoverflow.com/questions/2802341/javascript-natural-sort-of-alphanumerical-strings and also http://stackoverflow.com/questions/51165/how-do-you-do-string-comparison-in-javascript – Adriano Sep 26 '14 at 15:25
-
@Mark the `Natural Sort Order` is pretty "simply" implemented in your example and it might be of far too low quality for many people, just see how it sorts the basic latin characters http://jsbin.com/daseyutiyuji/1/edit?js,console . Why not use the browsers' built-in `localeCompare()` methods instead!? see a live demo http://jsbin.com/beboroyifomu/1/edit?js,console and also a discussion on this topic http://stackoverflow.com/questions/51165/how-do-you-do-string-comparison-in-javascript – Adriano Sep 29 '14 at 12:10
-
@AdrienBe good comment. The question was how to sort select options, and I think the answer illustrates that. The sort algorithm depends on what is being sorted and how it should be sorted. – Mark Oct 15 '14 at 23:49
-
it is also possible to shorten sort callback to `function(a,b) {return (a.text > b.text)-(a.text
– Marat Jul 21 '15 at 07:49 -
i used this solution instead of jquery because the jquery solution fails in IE11. however, when using the proposed solution in IE11 I found that the selection dialogue would not update automatically and I solved that issue by adding `$("#my_select").focus();`. – B5A7 Dec 14 '17 at 01:14
Modified Tom's answer above slightly so that it actually modifies the contents of the select box to be sorted, rather than just returning the sorted elements.
$('#your_select_box').sort_select_box();
jQuery function:
$.fn.sort_select_box = function(){
// Get options from select box
var my_options = $("#" + this.attr('id') + ' option');
// sort alphabetically
my_options.sort(function(a,b) {
if (a.text > b.text) return 1;
else if (a.text < b.text) return -1;
else return 0
})
//replace with sorted my_options;
$(this).empty().append( my_options );
// clearing any selections
$("#"+this.attr('id')+" option").attr('selected', false);
}

- 1,360
- 14
- 11
I've just wrapped Mark's idea in a jquery function
$('#your_select_box').sort_select_box();
JQuery function:
$.fn.sort_select_box = function(){
var my_options = $("#" + this.attr('id') + ' option');
my_options.sort(function(a,b) {
if (a.text > b.text) return 1;
else if (a.text < b.text) return -1;
else return 0
})
return my_options;
}

- 1,969
- 3
- 21
- 24
-
how could i add this to my current click event ? $('#addwire').click(function() { return !$('#wireselection option:selected').remove().appendTo('#wires').sort_select_box(); }); doens't seem to work – mcgrailm Feb 25 '11 at 20:32
The solution I mentioned in my comment to @Juan Perez
$.fn.sortOptions = function(){
$(this).each(function(){
var op = $(this).children("option");
op.sort(function(a, b) {
return a.text > b.text ? 1 : -1;
})
return $(this).empty().append(op);
});
}
Usage:
$("select").sortOptions();
This can still be improved on, but I didn't need to add any more bells or whistles :)

- 4,184
- 2
- 24
- 29
Well, in IE6 it seems to sort on the nested array's [0] item:
function sortSelect(selectToSort) {
var arrOptions = [];
for (var i = 0; i < selectToSort.options.length; i++) {
arrOptions[i] = [];
arrOptions[i][0] = selectToSort.options[i].value;
arrOptions[i][1] = selectToSort.options[i].text;
arrOptions[i][2] = selectToSort.options[i].selected;
}
arrOptions.sort();
for (var i = 0; i < selectToSort.options.length; i++) {
selectToSort.options[i].value = arrOptions[i][0];
selectToSort.options[i].text = arrOptions[i][1];
selectToSort.options[i].selected = arrOptions[i][2];
}
}
I'll see if this works in other browsers...
Edit: it works in Firefox too, woo hoo!
Is there an easier way than this though? is there some method built into javascript or jQuery that sorts selects that I am missing, or is this the best way?

- 35,751
- 21
- 71
- 94
-
8Note that this function does not sort the **option** elements; it changes the *[value,text,selected]* on the existing elements such that they are sorted (by value in this case). This is sufficient for most applications, but if you have other attributes (CSS, tool tips, etc.) then this approach will not suffice. – NVRAM Dec 02 '09 at 19:51
There's a closed jQuery ticket for a sort that should work, but just wasn't included in the core.
jQuery.fn.sort = function() {
return this.pushStack( [].sort.apply( this, arguments ), []);
};
Referenced from a Google Groups thread, I think you just pass in a function that is used to sort, like so
function sortSelect(selectToSort) {
jQuery(selectToSort.options).sort(function(a,b){
return a.value > b.value ? 1 : -1;
});
}
Hope it helps!

- 152,002
- 23
- 148
- 175
-
1Some issues about the sortSelect function: This doesn't consider equal options. Sorts according to value and not text. jQuery objects don't have a property named "options". Doesn't have any effect, because you have to append the options to a new select element. – simon Apr 11 '12 at 07:43
This is a better solution. Declare a global function to JQuery
$.fn.sortSelect = function() {
var op = this.children("option");
op.sort(function(a, b) {
return a.text > b.text ? 1 : -1;
})
return this.empty().append(op);
}
And call the function from the code.
$("#my_select").sortSelect();

- 41
- 1
-
1I used a variation on this, wrapping the inner part in $(this).each() so I could pass it a selector to handle more than one at once. – Tom Pietrosanti Sep 06 '12 at 19:24
-
1
Array.sort()
defaults to converting each element to a string, and comparing those values. So ["value", "text", "selected"]
gets sorted as "value, text, selected"
. Which will probably work fine, most of the time.
If you do want to sort on value alone, or interpret value as a number, then you can pass a comparison function into sort():
arrOptions.sort(function(a,b) { return new Number(a[0]) - new Number(b[0]); });

- 156,901
- 35
- 231
- 235
A bit late but for what it's worth I've implemented a more complex function you can include generically. It has a few options for varied output. It can also recurse into <OPTGROUP>
tags based on their label.
$.fn.sortSelect = function(options){
const OPTIONS_DEFAULT = {
recursive: true, // Recurse into <optgroup>
reverse: false, // Reverse order
useValues: false, // Use values instead of text for <option> (<optgruop> is always label based)
blankFirst: true, // Force placeholder <option> with empty value first, ignores reverse
}
if (typeof options != "object" || null === options) {
options = OPTIONS_DEFAULT;
}
var sortOptions = function($root, $node, options){
if ($node.length != 1) {
return false;
}
if ($node[0].tagName != "SELECT" && $node[0].tagName != "OPTGROUP") {
return false;
}
if (options.recursive) {
$node.children('optgroup').each(function(k, v){
return sortOptions($root, $(v), options);
});
}
var $options = $node.children('option, optgroup');
var $optionsSorted = $options.sort(function(a, b){
if (options.blankFirst) {
if (a.tagName == "OPTION" && a.value == "") {
return -1;
}
if (b.tagName == "OPTION" && b.value == "") {
return 1;
}
}
var textA = (a.tagName == "OPTION" ? (options.useValues ? a.value : a.text) : a.label);
var textB = (b.tagName == "OPTION" ? (options.useValues ? a.value : b.text) : b.label);
if (textA > textB) {
return options.reverse ? -1 : 1;
}
if (textA < textB) {
return options.reverse ? 1 : -1;
}
return 0;
});
$options.remove();
$optionsSorted.appendTo($node);
return true;
};
var selected = $(this).val();
var sorted = sortOptions($(this), $(this), {...OPTIONS_DEFAULT, ...options});
$(this).val(selected);
return sorted;
};
You can then call the sortSelect()
function on any <SELECT>
tag, or just a single <OPTGROUP>
to only sort a group's options.
Example:
$('select').sortSelect();
Reverse order using the "reverse" option:
$('select').sortSelect({
reverse: true
});
You could apply this to all selects automatically, perhaps only if they include an important class (e.g. "js-sort") with this:
$('select.js-sort').each(function(k, v){
$(v).sortSelect();
});

- 1,096
- 1
- 9
- 18
Remember: if you want to use context selector, just concatenate the ID will not work
$.fn.sort_select_box = function(){
var my_options = $("option", $(this));
my_options.sort(function(a,b) {
if (a.text > b.text) return 1;
else if (a.text < b.text) return -1;
else return 0
});
$(this).empty().append(my_options);
}
// Usando:
$("select#ProdutoFornecedorId", $($context)).sort_select_box();

- 120
- 1
- 10
Seems jquery still is not particularly helpful enough for sorting options in a html select element. Here is some plain-plain javascript code for sorting options:
function sortOptionsByText(a,b) {
// I keep an empty value option on top, b.value comparison to 0 might not be necessary if empty value is always on top...
if (a.value.length==0 || (b.value.length>0 && a.text <= b.text)) return -1; // no sort: a, b
return 1; // sort switches places: b, a
}
function sortOptionsByValue(a,b) {
if (a.value <= b.value) return -1; // a, b
return 1; // b, a
}
function clearChildren(elem) {
if (elem) {
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}
}
function sortSelectElem(sel,byText) {
const val=sel.value;
const tmp=[...sel.options];
tmp.sort(byText?sortOptionsByText:sortOptionsByValue);
clearChildren(sel);
sel.append(...tmp);
sel.value=val;
}
RACE: <select id="list" size="6">
<option value="">--PICK ONE--</option>
<option value="1">HUMANOID</option>
<option value="2">AMPHIBIAN</option>
<option value="3">REPTILE</option>
<option value="4">INSECTOID</option>
</select><br>
<button type="button" onclick="sortSelectElem(document.getElementById('list'));">SORT LIST BY VALUE</button><br>
<button type="button" onclick="sortSelectElem(document.getElementById('list'),true);">SORT LIST BY TEXT</button>

- 35
- 1
- 6
With jquery this worked for me in Chrome in order to sort a select made from database unsorted elements.
$(document).ready(function(){
var $list = $("#my_select");
var selected = $("#my_select").val(); //save selected value
$list.children().detach().sort(function(a, b) {
return $(a).text().localeCompare($(b).text());
}).appendTo($list); //do the sorting locale for latin chars
$("#my_select").val(selected); //select previous selected value
});

- 454
- 4
- 12