Javascript для сортировки содержимого элемента select

есть ли быстрый способ сортировки элементов элемента select? Или мне придется прибегнуть к написанию javascript?

пожалуйста, любые идеи.

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

18 ответов


это сделает трюк. Просто передайте ему свой элемент select a la:document.getElementById('lstALL') когда вам нужен сортированный список.

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

Это решение очень хорошо работало для меня, используя jquery, думал, что я буду ссылаться на него здесь,поскольку я нашел эту страницу перед другой. Кто-то другой мог бы сделать то же самое.

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

С сортировка выпадающего списка с помощью Javascript


с W3C ПО ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ:

хотя многие языки программирования имеют такие устройства, как раскрывающиеся окна, которые имеют возможность сортировки списка элементов перед их отображением как часть их функциональности, функция HTML

вам придется сортировать их вручную для статического HTML-документа или прибегать к Javascript или какой-либо другой программной сортировке для динамический документ.


У меня была та же проблема. Вот решение jQuery Я придумал:

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

другой вариант:

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

работая с ответами, предоставленными Марко Лаццери и Терре Портером (проголосуйте за них, если этот ответ полезен), я придумал немного другое решение, которое сохраняет выбранное значение (вероятно, не сохраняет обработчики событий или прикрепленные данные), используя 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 любимых ответов на этой доске:

  • лучший и самый простой ответ jOk.
  • простой метод jQuery Терри Портера.
  • функция SmokeyPHP конфигурируемая.

результаты легки для использования, и легко конфигурируемая функция.

первым аргументом может быть объект select, идентификатор объекта select или массив, имеющий не менее 2 измерений.

второй аргумент является необязательным. По умолчанию сортировка по тексту опции, индекс 0. Может быть передан любой другой индекс, поэтому сортируйте по нему. Можно пройти 1, или текст "значение", для сортировки по значению.

Сортировать по текстовым примерам (все будут сортировать по тексту):

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

Сортировать по значению (все будут сортировать по значению):

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

сортировка любого массива по другому индексу:

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

sortSelect(myArray,2);

этот последний будет сортировать массив по индексу-2, sortme.

основные функции вида

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

да док имеет правильный ответ ... либо предварительно отсортируйте результаты перед написанием HTML (предполагая, что он динамический, и вы отвечаете за вывод), либо напишите javascript.

на Сортировка Javascript способ будет вашим другом здесь. Просто вытащите значения из списка выбора, затем отсортируйте их и верните: -)


Í думаю, что это лучший вариант (я использую код @Matty и улучшен!):

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

я использовал эту сортировку пузырьков, потому что я не смог заказать их .значение в массиве options и это было число. Так я их правильно заказал. Надеюсь, вам это тоже пригодится.

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

у меня была аналогичная проблема, за исключением того, что я хотел, чтобы выбранные элементы отображались сверху, и я не хотел очищать, какие элементы были выбраны (список с несколькими вариантами). Мой основан на 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);
}

без выбранного сверху, это будет выглядеть так.

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

я быстро собрал тот, который позволяет выбирать направление ("asc" или "desc"), должно ли сравнение выполняться по значению опции (true или false) и следует ли обрезать перед сравнением (boolean) ведущие и конечные пробелы.

преимущество этого метода заключается в том, что выбранный выбор сохраняется, и все другие специальные свойства/триггеры также должны быть сохранены.

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*$/,'');
                opts[i].value = opts[i].value.replace(/^\s*(.*)\s*$/,'');
            }
            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;
}

вдохновленный ответом @Terre Porter, я думаю, что это очень просто реализовать (используя 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
})

но, для Альфа / числовых выпадающих списков:

вдохновленный: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;
    }
})

надеюсь, что это поможет

First exampleSecond example


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

идея состоит в том, чтобы вытащить все элементы selectbox в массив, удалить значения selectbox, чтобы избежать переопределения, отсортировать массив, а затем вернуть отсортированный массив в поле выбора


не совсем так красиво, как пример JQuery Марко, но с прототипом (возможно, мне не хватает более элегантного решения) это будет:

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

а затем просто передайте ему элемент select:

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

еще один способ сделать это с помощью 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);
});

попробуйте это...надеюсь, он предложит вам решение:

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>

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