web-dev-qa-db-fra.com

Javascript pour trier le contenu de l'élément sélectionné

existe-t-il un moyen rapide de trier les éléments d'un élément sélectionné? Ou je dois recourir à l'écriture javascript?

S'il vous plaît des idées.

<select size="4" name="lstALL" multiple="multiple" id="lstALL" tabindex="12" style="font-size:XX-Small;height:95%;width:100%;">
<option value="0"> XXX</option>
<option value="1203">ABC</option>
<option value="1013">MMM</option>
</select>
35
Julius A

Ça fera l'affaire. Passez-y simplement votre élément de sélection à la: document.getElementById('lstALL') lorsque vous avez besoin de trier votre liste.

function sortSelect(selElem) {
    var tmpAry = new Array();
    for (var i=0;i<selElem.options.length;i++) {
        tmpAry[i] = new Array();
        tmpAry[i][0] = selElem.options[i].text;
        tmpAry[i][1] = selElem.options[i].value;
    }
    tmpAry.sort();
    while (selElem.options.length > 0) {
        selElem.options[0] = null;
    }
    for (var i=0;i<tmpAry.length;i++) {
        var op = new Option(tmpAry[i][0], tmpAry[i][1]);
        selElem.options[i] = op;
    }
    return;
}
64
Matty

Cette solution a très bien fonctionné pour moi en utilisant jquery, j'ai pensé la croiser ici car j'ai trouvé cette page avant l'autre. Quelqu'un d'autre pourrait faire de même.

$("#id").html($("#id option").sort(function (a, b) {
    return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
}))

de liste déroulante de tri utilisant Javascript

38
Terre Porter

De la FAQ W3C :

Bien que de nombreux langages de programmation aient des dispositifs tels que des listes déroulantes qui ont la capacité de trier une liste d'éléments avant de les afficher dans le cadre de leurs fonctionnalités, la fonction HTML <select> n'a pas de telles capacités. Il répertorie les <options> dans l'ordre reçu.

Vous devez les trier à la main pour un document HTML statique, ou recourir à Javascript ou à un autre tri programmé pour un document dynamique.

4
Bill the Lizard

En travaillant avec les réponses fournies par Marco Lazzeri et Terre Porter (votez-les si cette réponse est utile), j'ai trouvé une solution légèrement différente qui préserve la valeur sélectionnée (cependant ne préserve probablement pas les gestionnaires d'événements ou les données jointes) en utilisant jQuery.

// save the selected value for sorting
var v = jQuery("#id").val();

// sort the options and select the value that was saved
j$("#id")
    .html(j$("#id option").sort(function(a,b){
        return a.text == b.text ? 0 : a.text < b.text ? -1 : 1;}))
    .val(v);
3
Matt K

J'ai eu le même problème. Voici la solution jQuery J'ai trouvé:

  var options = jQuery.makeArray(optionElements).
                       sort(function(a,b) {
                         return (a.innerHTML > b.innerHTML) ? 1 : -1;
                       });
  selectElement.html(options);
3
Marco Lazzeri

Une autre option:

function sortSelect(elem) {
    var tmpAry = [];
    // Retain selected value before sorting
    var selectedValue = elem[elem.selectedIndex].value;
    // Grab all existing entries
    for (var i=0;i<elem.options.length;i++) tmpAry.Push(elem.options[i]);
    // Sort array by text attribute
    tmpAry.sort(function(a,b){ return (a.text < b.text)?-1:1; });
    // Wipe out existing elements
    while (elem.options.length > 0) elem.options[0] = null;
    // Restore sorted elements
    var newSelectedIndex = 0;
    for (var i=0;i<tmpAry.length;i++) {
        elem.options[i] = tmpAry[i];
        if(elem.options[i].value == selectedValue) newSelectedIndex = i;
    }
    elem.selectedIndex = newSelectedIndex; // Set new selected index after sorting
    return;
}
3
user684486

Ceci est une recompilation de mes 3 réponses préférées sur ce forum:

  • la meilleure et la plus simple réponse de jOk.
  • La méthode jQuery facile de Terry Porter.
  • Fonction configurable de SmokeyPHP.

Les résultats sont une fonction facile à utiliser et facilement configurable.

Le premier argument peut être un objet de sélection, l'ID d'un objet de sélection ou un tableau d'au moins 2 dimensions.

Le deuxième argument est facultatif. Par défaut, le tri est basé sur le texte de l'option, l'index 0. Vous pouvez passer n'importe quel autre index, alors triez-le. Peut être passé 1, ou le texte "valeur", pour trier par valeur.

Trier par des exemples de texte (tous seraient triés par texte):

 sortSelect('select_object_id');
 sortSelect('select_object_id', 0);
 sortSelect(selectObject);
 sortSelect(selectObject, 0);

Trier par valeur (tous seraient triés par valeur):

 sortSelect('select_object_id', 'value');
 sortSelect('select_object_id', 1);
 sortSelect(selectObject, 1);

Trier n'importe quel tableau par un autre index:

var myArray = [
  ['ignored0', 'ignored1', 'Z-sortme2'],
  ['ignored0', 'ignored1', 'A-sortme2'],
  ['ignored0', 'ignored1', 'C-sortme2'],
];

sortSelect(myArray,2);

Ce dernier triera le tableau par index-2, le sortme.

Fonction de tri principale

function sortSelect(selElem, sortVal) {

    // Checks for an object or string. Uses string as ID. 
    switch(typeof selElem) {
        case "string":
            selElem = document.getElementById(selElem);
            break;
        case "object":
            if(selElem==null) return false;
            break;
        default:
            return false;
    }

    // Builds the options list.
    var tmpAry = new Array();
    for (var i=0;i<selElem.options.length;i++) {
        tmpAry[i] = new Array();
        tmpAry[i][0] = selElem.options[i].text;
        tmpAry[i][1] = selElem.options[i].value;
    }

    // allows sortVal to be optional, defaults to text.
    switch(sortVal) {
        case "value": // sort by value
            sortVal = 1;
            break;
        default: // sort by text
            sortVal = 0;
    }
    tmpAry.sort(function(a, b) {
        return a[sortVal] == b[sortVal] ? 0 : a[sortVal] < b[sortVal] ? -1 : 1;
    });

    // removes all options from the select.
    while (selElem.options.length > 0) {
        selElem.options[0] = null;
    }

    // recreates all options with the new order.
    for (var i=0;i<tmpAry.length;i++) {
        var op = new Option(tmpAry[i][0], tmpAry[i][1]);
        selElem.options[i] = op;
    }

    return true;
}
2
Tony Chiboucas

Inspiré par la réponse de @Terre Porter, je pense que celle-ci est très simple à mettre en œuvre (en utilisant jQuery)

var $options = jQuery("#my-dropdownlist-id > option"); 
// or jQuery("#my-dropdownlist-id").find("option")

$options.sort(function(a, b) {
    return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
})

Mais, pour les listes déroulantes Alpha/Numérique:

Inspiré par: https://stackoverflow.com/a/4340339/1598891

var $options = jQuery(dropDownList).find("option");

var reAlpha = /[^a-zA-Z]/g;
var reNumeric = /[^0-9]/g;
$options.sort(function AlphaNumericSort($a,$b) {
    var a = $a.text;
    var b = $b.text;
    var aAlpha = a.replace(reAlpha, "");
    var bAlpha = b.replace(reAlpha, "");
    if(aAlpha === bAlpha) {
        var aNumeric = parseInt(a.replace(reNumeric, ""), 10);
        var bNumeric = parseInt(b.replace(reNumeric, ""), 10);
        return aNumeric === bNumeric ? 0 : aNumeric > bNumeric ? 1 : -1;
    } else {
        return aAlpha > bAlpha ? 1 : -1;
    }
})

J'espère que cela vous aidera

First exampleSecond example

1
RPDeshaies

J'ai utilisé ce type de bulle car je ne pouvais pas les commander par la valeur. Dans le tableau d'options et c'était un nombre. De cette façon, je les ai correctement commandés. J'espère que cela vous sera utile aussi.

function sortSelect(selElem) {
  for (var i=0; i<(selElem.options.length-1); i++)
      for (var j=i+1; j<selElem.options.length; j++)
          if (parseInt(selElem.options[j].value) < parseInt(selElem.options[i].value)) {
              var dummy = new Option(selElem.options[i].text, selElem.options[i].value);
              selElem.options[i] = new Option(selElem.options[j].text, selElem.options[j].value);
              selElem.options[j] = dummy;
          }
}
1
Soledad

Oui, DOK a la bonne réponse ... soit pré-trier les résultats avant d'écrire le HTML (en supposant qu'il est dynamique et que vous êtes responsable de la sortie), soit écrivez javascript.

La méthode Javascript Sort sera votre amie ici. Retirez simplement les valeurs de la liste de sélection, puis triez-les et remettez-les :-)

1
Joel Martinez
function call() {
    var x = document.getElementById("mySelect");
    var optionVal = new Array();

    for (i = 0; i < x.length; i++) {
        optionVal.Push(x.options[i].text);
    }

    for (i = x.length; i >= 0; i--) {
        x.remove(i);
    }

    optionVal.sort();

    for (var i = 0; i < optionVal.length; i++) {
        var opt = optionVal[i];
        var el = document.createElement("option");
        el.textContent = opt;
        el.value = opt;
        x.appendChild(el);
    }
}

L'idée est de retirer tous les éléments de la boîte de sélection dans un tableau, de supprimer les valeurs de la boîte de sélection pour éviter de remplacer, de trier le tableau, puis de repousser le tableau trié dans la boîte de sélection

1
Arijit Basu

J'en ai rapidement réuni un qui permet de choisir la direction ("asc" ou "desc"), si la comparaison doit être effectuée sur la valeur de l'option (vrai ou faux) et si les espaces de début et de fin doivent être coupés avant la comparaison (booléen).

L'avantage de cette méthode est que le choix sélectionné est conservé et que toutes les autres propriétés/déclencheurs spéciaux doivent également être conservés.

function sortOpts(select,dir,value,trim)
{
    value = typeof value == 'boolean' ? value : false;
    dir = ['asc','desc'].indexOf(dir) > -1 ? dir : 'asc';
    trim = typeof trim == 'boolean' ? trim : true;
    if(!select) return false;
    var opts = select.getElementsByTagName('option');

    var options = [];
    for(var i in opts)
    {
        if(parseInt(i)==i)
        {
            if(trim)
            {
                opts[i].innerHTML = opts[i].innerHTML.replace(/^\s*(.*)\s*$/,'$1');
                opts[i].value = opts[i].value.replace(/^\s*(.*)\s*$/,'$1');
            }
            options.Push(opts[i]);
        }
    }
    options.sort(value ? sortOpts.sortVals : sortOpts.sortText);
    if(dir == 'desc') options.reverse();
    options.reverse();
    for(var i in options)
    {
        select.insertBefore(options[i],select.getElementsByTagName('option')[0]);
    }
}
sortOpts.sortText = function(a,b) {
    return a.innerHTML > b.innerHTML ? 1 : -1;
}
sortOpts.sortVals = function(a,b) {
    return a.value > b.value ? 1 : -1;
}
1
SmokeyPHP

Je pense que c'est une meilleure option (j'utilise le code de @ Matty et amélioré!):

function sortSelect(selElem, bCase) {
                var tmpAry = new Array();
                bCase = (bCase ? true : false);
                for (var i=0;i<selElem.options.length;i++) {
                        tmpAry[i] = new Array();
                        tmpAry[i][0] = selElem.options[i].text;
                        tmpAry[i][1] = selElem.options[i].value;
                }
                if (bCase)
                    tmpAry.sort(function (a, b) {
                        var ret = 0;
                        var iPos = 0;
                        while (ret == 0 && iPos < a.length && iPos < b.length)
                        {
                            ret = (String(a).toLowerCase().charCodeAt(iPos) - String(b).toLowerCase().charCodeAt(iPos));
                            iPos ++;
                        }
                        if (ret == 0)
                        {
                            ret = (String(a).length - String(b).length);
                        }
                        return ret;
                        });
                else
                    tmpAry.sort();
                while (selElem.options.length > 0) {
                    selElem.options[0] = null;
                }
                for (var i=0;i<tmpAry.length;i++) {
                        var op = new Option(tmpAry[i][0], tmpAry[i][1]);
                        selElem.options[i] = op;
                }
                return;
        }
1
Matias P.

J'ai eu un problème similaire, sauf que je voulais que les éléments sélectionnés apparaissent en haut, et je ne voulais pas effacer les éléments sélectionnés (liste multi-sélection). Le mien est basé sur jQuery ...

function SortMultiSelect_SelectedTop(slt) {
    var options =
        $(slt).find("option").sort(function (a, b) {
            if (a.selected && !b.selected) return -1;
            if (!a.selected && b.selected) return 1;
            if (a.text < b.text) return -1;
            if (a.text > b.text) return 1;
            return 0;
        });
    $(slt).empty().append(options).scrollTop(0);
}

Sans sélectionné en haut, cela ressemblerait à ceci.

function SortMultiSelect(slt) {
    var options =
        $(slt).find("option").sort(function (a, b) {
            if (a.text < b.text) return -1;
            if (a.text > b.text) return 1;
            return 0;
        });
    $(slt).empty().append(options).scrollTop(0);
}
1
colinbashbash

Pas aussi joli que l'exemple JQuery de Marco mais avec prototype (il me manque peut-être une solution plus élégante) ce serait:

function sort_select(select) {
  var options = $A(select.options).sortBy(function(o) { return o.innerHTML });
  select.innerHTML = "";
  options.each(function(o) { select.insert(o); } );
}

Et puis passez-lui un élément select:

sort_select( $('category-select') );
0
Geoff

Essayez ceci ... j'espère que cela vous offrira une solution:

function sortlist_name()
{

    var lb = document.getElementById('mylist');
    arrTexts = new Array();
    newTexts = new Array();
    txt = new Array();
    newArray =new Array();
    for(i=0; i<lb.length; i++)
    {
      arrTexts[i] = lb.options[i].text;
    }
    for(i=0;i<arrTexts.length; i++)
    {
        str = arrTexts[i].split(" -> ");
        newTexts[i] = str[1]+' -> '+str[0];
    }
    newTexts.sort();
    for(i=0;i<newTexts.length; i++)
    {
        txt = newTexts[i].split(' -> ');
        newArray[i] = txt[1]+' -> '+txt[0];
    }
    for(i=0; i<lb.length; i++)
    {
        lb.options[i].text = newArray[i];
        lb.options[i].value = newArray[i];
    }
}
/***********revrse by name******/
function sortreverse_name()
{

    var lb = document.getElementById('mylist');
    arrTexts = new Array();
    newTexts = new Array();
    txt = new Array();
    newArray =new Array();
    for(i=0; i<lb.length; i++)
    {
      arrTexts[i] = lb.options[i].text;
    }
    for(i=0;i<arrTexts.length; i++)
    {
        str = arrTexts[i].split(" -> ");
        newTexts[i] = str[1]+' -> '+str[0];
    }
    newTexts.reverse();
    for(i=0;i<newTexts.length; i++)
    {
        txt = newTexts[i].split(' -> ');
        newArray[i] = txt[1]+' -> '+txt[0];
    }
    for(i=0; i<lb.length; i++)
    {
        lb.options[i].text = newArray[i];
        lb.options[i].value = newArray[i];
    }
}

function sortlist_id() {
var lb = document.getElementById('mylist');
arrTexts = new Array();

for(i=0; i<lb.length; i++)  {
  arrTexts[i] = lb.options[i].text;
}

arrTexts.sort();

for(i=0; i<lb.length; i++)  {
  lb.options[i].text = arrTexts[i];
  lb.options[i].value = arrTexts[i];
}
}

/***********revrse by id******/
function sortreverse_id() {
var lb = document.getElementById('mylist');
arrTexts = new Array();

for(i=0; i<lb.length; i++)  {
  arrTexts[i] = lb.options[i].text;
}

arrTexts.reverse();

for(i=0; i<lb.length; i++)  {
  lb.options[i].text = arrTexts[i];
  lb.options[i].value = arrTexts[i];
}
}
</script>



  ID<a href="javascript:sortlist_id()"> &#x25B2;  </a> <a href="javascript:sortreverse_id()">&#x25BC;</a> |  Name<a href="javascript:sortlist_name()"> &#x25B2;  </a> <a href="javascript:sortreverse_name()">&#x25BC;</a><br/>

<select name=mylist id=mylist size=8 style='width:150px'>

<option value="bill">4 -> Bill</option>
<option value="carl">5 -> Carl</option>
<option value="Anton">1 -> Anton</option>
<option value="mike">2 -> Mike</option>
<option value="peter">3 -> Peter</option>
</select>
<br>
0
Krishna Kamat

Exemple de tri des options de localisation de Vanilla JS es6

const optionNodes = Array.from(selectNode.children);
const comparator = new Intl.Collator(lang.slice(0, 2)).compare;

optionNodes.sort((a, b) => comparator(a.textContent, b.textContent));
optionNodes.forEach((option) => selectNode.appendChild(option));

Mon cas d'utilisation était de localiser une liste déroulante de sélection de pays avec un tri tenant compte des paramètres régionaux. Cela a été utilisé sur plus de 250 options et était très performant ~ 10ms sur ma machine.

0
protoEvangelion
function sortItems(c) {
var options = c.options;
Array.prototype.sort.call(options, function (a, b) {
    var aText = a.text.toLowerCase();
    var bText = b.text.toLowerCase();
    if (aText < bText) {
        return -1;
    } else if (aText > bText) {
        return 1;
    } else {
        return 0;
    }
});
}

sortItems(document.getElementById('lstALL'));
0
Joel

Juste une autre façon de le faire avec jQuery:

// sorting;
var selectElm = $("select"),
    selectSorted = selectElm.find("option").toArray().sort(function (a, b) {
        return (a.innerHTML.toLowerCase() > b.innerHTML.toLowerCase()) ? 1 : -1;
    });
selectElm.empty();
$.each(selectSorted, function (key, value) {
    selectElm.append(value);
});
0
jerone