Qual é a maneira mais eficiente de classificar as opções de um Html Select por valor, preservando o item atualmente selecionado?

StackOverflow https://stackoverflow.com/questions/45888

Pergunta

Eu tenho o jQuery, mas não tenho certeza se ele possui algum auxiliar de classificação integrado.Eu poderia fazer um array 2D de cada item text, value, e selected propriedades, mas não acho que o javascript esteja embutido Array.sort() funcionaria corretamente.

Foi útil?

Solução

Extraia as opções em um array temporário, classifique e reconstrua a lista:

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);

Documentação de classificação da Mozilla (especificamente a compareFunction) e Página do algoritmo de classificação da Wikipedia são relevantes.

Se você quiser tornar a classificação insensível a maiúsculas e minúsculas, substitua text com text.toLowerCase()

A função de classificação mostrada acima ilustra como classificar.Classificar com precisão idiomas diferentes do inglês pode ser complexo (consulte o algoritmo de agrupamento unicode).Usando localeComparar na função sort é uma boa solução, por exemplo:

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

Outras dicas

Modifiquei ligeiramente a resposta de Tom acima para que ela realmente modifique o conteúdo da caixa de seleção a ser classificada, em vez de apenas retornar os elementos classificados.

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

Função 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);
}

Acabei de envolver a ideia de Mark em uma função jquery

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

Função 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;
}

A solução que mencionei em meu comentário para @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);
    });
}

Uso:

$("select").sortOptions();

Isso ainda pode ser melhorado, mas não precisei adicionar mais sinos ou assobios :)

um ticket jQuery fechado para um tipo que deveria funcionar, mas simplesmente não foi incluído no núcleo.

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

Referenciado de um tópico dos Grupos do Google, acho que você acabou de passar uma função que é usada para classificar, assim

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

Espero que ajude!

Bem, no IE6 parece classificar o item [0] do array aninhado:

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

Vou ver se isso funciona em outros navegadores...

Editar:funciona no Firefox também, uau!

Existe uma maneira mais fácil do que isso?existe algum método embutido em javascript ou jQuery que classifica as seleções que estou faltando ou essa é a melhor maneira?

Esta é uma solução melhor.Declare uma função global para 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);
}

E chame a função do código.

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

Array.sort() o padrão é converter cada elemento em uma string e comparar esses valores.Então ["value", "text", "selected"] é classificado como "value, text, selected".O que provavelmente funcionará bem, na maioria das vezes.

Se você quiser classificar apenas o valor ou interpretar o valor como um número, poderá passar uma função de comparação para sort():

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

Lembrar:se você quiser usar o seletor de contexto, apenas concatenar o ID não funcionará

$.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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top