¿Cuál es la forma más eficiente de ordenar las opciones de una selección HTML por valor, conservando al mismo tiempo el elemento seleccionado actualmente?

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

Pregunta

Tengo jQuery pero no estoy seguro de si tiene ayudas de clasificación integradas.Podría hacer una matriz 2D de cada elemento. text, value, y selected propiedades, pero no creo que javascript esté integrado Array.sort() funcionaría correctamente.

¿Fue útil?

Solución

Extraiga opciones en una matriz temporal, ordénelas y luego reconstruya la 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);

Documentación de clasificación de Mozilla (específicamente la función de comparación) y Página del algoritmo de clasificación de Wikipedia es relevante.

Si desea que la clasificación no distinga entre mayúsculas y minúsculas, reemplace text con text.toLowerCase()

La función de clasificación que se muestra arriba ilustra cómo ordenar.Clasificar idiomas distintos del inglés con precisión puede ser complejo (consulte la algoritmo de intercalación Unicode).Usando localComparar en la función de clasificación es una buena solución, por ejemplo:

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

Otros consejos

Se modificó ligeramente la respuesta de Tom anterior para que realmente modifique el contenido del cuadro de selección que se va a ordenar, en lugar de simplemente devolver los elementos ordenados.

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

Función 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);
}

Acabo de incluir la idea de Mark en una función jquery.

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

Función 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;
}

La solución que mencioné en mi comentario a @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();

Esto todavía se puede mejorar, pero no necesité agregar más detalles :)

hay un ticket jQuery cerrado para un tipo que debería funcionar, pero que simplemente no estaba incluido en el núcleo.

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

Referenciado desde un hilo de Grupos de Google, Creo que simplemente pasas una función que se usa para ordenar, así

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

¡Espero eso ayude!

Bueno, en IE6 parece ordenarse según el elemento [0] de la matriz anidada:

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

Veré si esto funciona en otros navegadores...

Editar:También funciona en Firefox, ¡guau!

¿Existe una manera más fácil que esta?¿Existe algún método integrado en JavaScript o jQuery que ordene las selecciones que me faltan, o es esta la mejor manera?

Esta es una mejor solución.Declarar una función global a 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);
}

Y llame a la función desde el código.

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

Array.sort() El valor predeterminado es convertir cada elemento en una cadena y comparar esos valores.Entonces ["value", "text", "selected"] se clasifica como "value, text, selected".Lo cual probablemente funcionará bien la mayor parte del tiempo.

Si desea ordenar solo por valor o interpretar el valor como un número, puede pasar una función de comparación a sort():

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

Recordar:Si desea utilizar el selector de contexto, simplemente concatenar el ID no 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top