Qual é a maneira mais eficiente de classificar as opções de um Html Select por valor, preservando o item atualmente selecionado?
-
09-06-2019 - |
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.
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 :)
Há 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();