web-dev-qa-db-fra.com

Tri des éléments d'options par ordre alphabétique à l'aide de jQuery

J'essaie de comprendre le tri des éléments option au sein d'un élément select par ordre alphabétique. Idéalement, j'aimerais que cela soit une fonction distincte dans laquelle je peux simplement passer l'élément select car il doit être trié lorsque l'utilisateur clique sur certains boutons.

J'ai cherché haut et bas un bon moyen de le faire, mais je n'ai rien trouvé qui puisse fonctionner pour moi.

Les éléments d'option doivent être triés alphabétiquement par texte et non par valeur.

Est-ce possible d'une certaine manière?

67
bomortensen

Ce que je ferais c'est:

  1. Extrayez le texte et la valeur de chaque <option> Dans un tableau d'objets;
  2. Triez le tableau.
  3. Mettez à jour les éléments <option> Avec le contenu du tableau dans l'ordre.

Pour faire cela avec jQuery, vous pouvez faire ceci:

var options = $('select.whatever option');
var arr = options.map(function(_, o) { return { t: $(o).text(), v: o.value }; }).get();
arr.sort(function(o1, o2) { return o1.t > o2.t ? 1 : o1.t < o2.t ? -1 : 0; });
options.each(function(i, o) {
  o.value = arr[i].v;
  $(o).text(arr[i].t);
});

Voici un jsfiddle qui marche.

edit - Si vous souhaitez trier de manière à ignorer la casse alphabétique, vous pouvez utiliser JavaScript .toUpperCase() ou .toLowerCase() fonctions avant de comparer:

arr.sort(function(o1, o2) {
  var t1 = o1.t.toLowerCase(), t2 = o2.t.toLowerCase();

  return t1 > t2 ? 1 : t1 < t2 ? -1 : 0;
});
106
Pointy

La réponse acceptée n'est pas la meilleure dans tous les cas, car vous souhaitez parfois conserver des classes d'options et des arguments différents (par exemple, data-foo).

Ma solution est:

var sel = $('#select_id');
var selected = sel.val(); // cache selected value, before reordering
var opts_list = sel.find('option');
opts_list.sort(function(a, b) { return $(a).text() > $(b).text() ? 1 : -1; });
sel.html('').append(opts_list);
sel.val(selected); // set cached selected value

// Pour ie11 ou ceux qui obtiennent une option vide, remplacez html ('') empty ()

50
marxin
<select id="mSelect" >
    <option value="val1" > DEF </option>
    <option value="val4" > GRT </option>
    <option value="val2" > ABC </option>
    <option value="val3" > OPL </option>
    <option value="val5" > AWS </option>
    <option value="val9" > BTY </option>
</select>

.

$("#mSelect").append($("#mSelect option").remove().sort(function(a, b) {
    var at = $(a).text(), bt = $(b).text();
    return (at > bt)?1:((at < bt)?-1:0);
}));
28
Diode

html:

<select id="list">
    <option value="op3">option 3</option>
    <option value="op1">option 1</option>
    <option value="op2">option 2</option>
</select>

jQuery:

var options = $("#list option");                    // Collect options         
options.detach().sort(function(a,b) {               // Detach from select, then Sort
    var at = $(a).text();
    var bt = $(b).text();         
    return (at > bt)?1:((at < bt)?-1:0);            // Tell the sort function how to order
});
options.appendTo("#list");                          // Re-attach to select

J'ai utilisé la solution de tracevipin, qui a fonctionné à merveille. Je propose ici une version légèrement modifiée pour tous ceux qui, comme moi, aiment trouver du code facilement lisible et le compresser après c'est compris. J'ai aussi utilisé .detach au lieu de .remove pour conserver les liaisons sur les éléments optionnels DOM.

24
Gerbus

Voici ma version améliorée de solution de Pointy :

function sortSelectOptions(selector, skip_first) {
    var options = (skip_first) ? $(selector + ' option:not(:first)') : $(selector + ' option');
    var arr = options.map(function(_, o) { return { t: $(o).text(), v: o.value, s: $(o).prop('selected') }; }).get();
    arr.sort(function(o1, o2) {
      var t1 = o1.t.toLowerCase(), t2 = o2.t.toLowerCase();
      return t1 > t2 ? 1 : t1 < t2 ? -1 : 0;
    }); 
    options.each(function(i, o) {
        o.value = arr[i].v;
        $(o).text(arr[i].t);
        if (arr[i].s) {
            $(o).attr('selected', 'selected').prop('selected', true);
        } else {
            $(o).removeAttr('selected');
            $(o).prop('selected', false);
        }
    }); 
}

La fonction a le skip_first paramètre, ce qui est utile lorsque vous souhaitez conserver la première option, par exemple. quand c'est "choisissez ci-dessous:".

Il garde également une trace de l’option précédemment sélectionnée.

Exemple d'utilisation:

jQuery(document).ready(function($) {

  sortSelectOptions('#select-id', true);

});
4
Victor BV

Je sais que ce sujet est ancien, mais je pense que ma réponse peut être utile à beaucoup de gens.

Voici le plugin jQuery fabriqué à partir de la réponse de Pointy en utilisant ES6:

/**
 * Sort values alphabetically in select
 * source: http://stackoverflow.com/questions/12073270/sorting-options-elements-alphabetically-using-jquery
 */
$.fn.extend({
    sortSelect() {
        let options = this.find("option"),
            arr = options.map(function(_, o) { return { t: $(o).text(), v: o.value }; }).get();

        arr.sort((o1, o2) => { // sort select
            let t1 = o1.t.toLowerCase(), 
                t2 = o2.t.toLowerCase();
            return t1 > t2 ? 1 : t1 < t2 ? -1 : 0;
        });

        options.each((i, o) => {
            o.value = arr[i].v;
            $(o).text(arr[i].t);
        });
    }
});

L'utilisation est très facile

$("select").sortSelect();
2
Kuxa

Le plugin jquery.selectboxes.js a une méthode de tri. Vous pouvez implémenter le plugin ou plonger dans le code pour voir un moyen de trier les options.

1
Sam Tyson

Aucune des réponses n'a fonctionné pour moi. Pour une raison étrange, lorsque vous parcourez les options, chaque option ne renvoie rien lorsque la fonction text() est appelée. Au lieu de cela, j'ai été obligé de récupérer le libellé de l'option via attr('label')

/**
 * Sort the options of the target select list
 * alphabetically by label. For some reason, when
 * we call detach(), the returned options have no
 * text() and instead we're forced to get the option's
 * label via the 'label' attribute.
 * @param select jQuery selector
 */
function sort_multi_select(select) {
    var options = select.find('option');
    options.detach().sort(function (a, b) {
        var at = $(a).attr('label'), //label, not text()
            bt = $(b).attr('label');
        return at > bt ? 1 : at < bt ? -1 : 0;
    });
    options.appendTo(select);
}

//example
sort_multi_select($('#my_select'));
1
rmirabelle

Cela vous donnera une option pour les réorganiser manuellement si vous en avez besoin

Comment ordonneriez-vous de manière dynamique une liste <option select> en utilisant JQuery?

0
warmth

Oui, vous pouvez trier les options en fonction de son texte et les rajouter à la zone de sélection.

 function NASort(a, b) {    
      if (a.innerHTML == 'NA') {
          return 1;   
      }
      else if (b.innerHTML == 'NA') {
          return -1;   
      }       
      return (a.innerHTML > b.innerHTML) ? 1 : -1;
  };

Violon: https://jsfiddle.net/vaishali_ravisankar/5zfohf6v/

0
shali ravi

Malakgeorge answer est Nice et peut être facilement intégré à une fonction jQuery:

$.fn.sortSelectByText = function(){
    this.each(function(){
        var selected = $(this).val(); 
        var opts_list = $(this).find('option');
        opts_list.sort(function(a, b) { return $(a).text() > $(b).text() ? 1 : -1; });
        $(this).html('').append(opts_list);
        $(this).val(selected); 
    })
    return this;        
}
0
Dr Fred