Каков наиболее эффективный способ сортировки Html Select Options по значению, сохраняя текущий выбранный элемент?

У меня есть jQuery, но я не уверен, есть ли у него встроенные помощники сортировки. Я мог бы сделать 2d-массив каждого элемента text, value и selected свойств, но я не думаю, что javascript, встроенный в Array.sort(), будет работать правильно.

Ответ 1

Извлеките опции во временный массив, сортируйте, а затем перестройте список:

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 (в частности, compareFunction) и страница Wikipedia Sorting Algorithm.

Если вы хотите сделать регистр нечувствительным, замените text на text.toLowerCase()

Функция сортировки, показанная выше, показывает, как сортировать. Сортировка неанглийских языков может быть сложной (см. алгоритм сортировки unicode). Использование localeCompare в функции сортировки является хорошим решением, например:

my_options.sort(function(a,b) {
    return a.text.localeCompare(b.text);
});

Ответ 2

Модифицированный Tom ответит немного, чтобы он фактически изменял содержимое поля выбора для сортировки, а не просто возвращал отсортированные элементы.

$('#your_select_box').sort_select_box();

Функция jQuery:

$.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);
}

Ответ 3

Я только что завернул идею Mark в функцию jquery

$('#your_select_box').sort_select_box();

Функция JQuery:

$.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;
}

Ответ 4

Решение, упомянутое мной в комментарии к @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);
    });
}

Использование:

$("select").sortOptions();

Это все еще можно улучшить, но мне не нужно было добавлять больше колоколов или свистков:)

Ответ 5

Там закрытый jQuery билет для сортировки, который должен работать, но просто не был включен в ядро.

jQuery.fn.sort = function() {
  return this.pushStack( [].sort.apply( this, arguments ), []);
};

Ссылка из потока Google Groups, я думаю, вы просто передаете функцию, которая используется для сортировки, например

function sortSelect(selectToSort) {
    jQuery(selectToSort.options).sort(function(a,b){ 
        return a.value > b.value ? 1 : -1; 
    });
}

Надеюсь, что это поможет!

Ответ 6

Ну, в IE6, похоже, сортируется по вложенному массиву [0]:

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];
    }
}

Я посмотрю, работает ли это в других браузерах...

Изменить: он работает и в Firefox, woo hoo!

Есть ли более простой способ, чем это? есть ли какой-нибудь метод, встроенный в javascript или jQuery, который сортирует, который мне не хватает, или это лучший способ?

Ответ 7

Это лучшее решение. Объявить глобальную функцию для 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);
}

И вызовите функцию из кода.

$("#my_select").sortSelect();

Ответ 8

Array.sort() по умолчанию преобразует каждый элемент в строку и сравнивает эти значения. Поэтому ["value", "text", "selected"] сортируется как "value, text, selected". Который, вероятно, будет работать нормально, большую часть времени.

Если вы хотите сортировать только значение или интерпретировать значение как число, вы можете передать функцию сравнения в sort():

arrOptions.sort(function(a,b) { return new Number(a[0]) - new Number(b[0]); });

Ответ 9

Помните: если вы хотите использовать селектор контекста, просто конкатенация идентификатора не будет работать

$.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();

Ответ 10

var arrOptions = [];
var i = 0;
sel.find("option").each(function(){
    arrOptions[i] = [];
    arrOptions[i][0] = jQuery(this).text(); 
    arrOptions[i][1] = jQuery(this);
    i += 1;
});
arrOptions.sort();
for(var i=0;i<arrOptions.length;i++){
    sel.append(arrOptions[i][1]);       
}