84 votes

Quel est le moyen le plus efficace de trier les options d'une sélection Html par valeur, tout en conservant l'élément actuellement sélectionné ?

J'ai jQuery mais je ne suis pas sûr qu'il ait des aides de tri intégrées. Je pourrais créer un tableau de 2d de chaque élément text , value y selected mais je ne pense pas que les propriétés intégrées de javascript Array.sort() fonctionnerait correctement.

4 votes

Note à moi-même (puisque je suis revenu plusieurs fois sur cette question via google) : voici une bonne solution que vous avez écrite : gist.github.com/1072537

136voto

Mark Points 898

Extraire les options dans un tableau temporaire, trier, puis reconstruire la liste :

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

La documentation sur le triage de Mozilla (spécifiquement la compareFunction) et Page de Wikipédia sur l'algorithme de tri sont pertinentes.

Si vous voulez que le tri soit insensible à la casse, remplacez text con text.toLowerCase()

La fonction de tri présentée ci-dessus illustre la manière de trier. Trier des langues non anglaises de manière précise peut être complexe (voir la page algorithme de collation unicode ). Utilisation de localeCompare dans la fonction de tri est une bonne solution, par exemple :

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

1 votes

Je reviens sur cette question trois ans plus tard, et cette voie me semble la bonne.

8 votes

Notez que cette fonction est sensible à la casse -- c'est-à-dire qu'elle triera toutes les choses qui commencent par des lettres majuscules avant celles qui commencent par des lettres minuscules. Si cela n'est pas souhaitable, il suffit d'ajouter une balise .toUpperCase() après chaque .text

10 votes

De plus, l'option actuellement sélectionnée n'est pas conservée telle quelle dans tous les navigateurs (Chrome se souvient de ce qui a été sélectionné, mais pas firefox et ie, qui sélectionnent le dernier élément après la lecture des options). Pour résoudre ce problème, sauvegardez la valeur sélectionnée avant de trier, puis sélectionnez-la à nouveau. var selected = $("#my_select").val(); et ensuite, après avoir ajouté les options triées, rétablir la val, c'est-à-dire $("#my_select").val(selected);

20voto

JaredC Points 632

J'ai légèrement modifié la réponse de Tom ci-dessus pour qu'elle modifie réellement le contenu de la boîte de sélection à trier, plutôt que de simplement retourner les éléments triés.

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

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

1 votes

Cette réponse est proche du sommet, mais ne sélectionne pas correctement.

18voto

Tom Maeckelberghe Points 1058

Je viens d'intégrer l'idée de Mark dans une fonction jquery.

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

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

0 votes

Comment puis-je ajouter ceci à mon événement de clic actuel ? $('#addwire').click(function() { return !$('#wireselection option:selected').remove().appendTo('#wires').sort_select_box() ; }) ; cela ne semble pas fonctionner.

12voto

Tom Pietrosanti Points 2299

La solution que j'ai mentionnée dans mon commentaire à @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);
    });
}

Utilisation :

$("select").sortOptions();

Il est encore possible de l'améliorer, mais je n'ai pas eu besoin d'ajouter de clochettes ou de sifflets supplémentaires :)

6voto

bdukes Points 54833

Il y a un ticket jQuery fermé pour une sorte qui devrait fonctionner, mais qui n'a pas été incluse dans le noyau.

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

Référencé à partir de un fil de discussion sur Google Groups je pense qu'il suffit de passer dans une fonction qui est utilisée pour trier, comme ça

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

J'espère que cela vous aidera !

1 votes

Quelques problèmes concernant la fonction sortSelect : Elle ne prend pas en compte les options égales. Elle trie en fonction de la valeur et non du texte. Les objets jQuery n'ont pas de propriété nommée "options". Cela n'a aucun effet, car vous devez ajouter les options à un nouvel élément select.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X