Сортировка элементов опций в алфавитном порядке с помощью jQuery


Я пытаюсь понять сортировки option элементы внутри a select элемент в алфавитном порядке. В идеале, я хотел бы иметь это как отдельную функцию, где я могу просто передать элемент select, так как он должен быть отсортирован, когда пользователь нажимает некоторые кнопки.

Я искал повсюду хороший способ сделать это, но не смог найти ничего, что работало на меня.

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

возможно ли каким-то образом?

11 59

11 ответов:

что бы я сделал:

  1. извлеките текст и значение каждого <option> в массив объектов;
  2. сортировка массива;
  3. обновить <option> элементы с содержимым массива по порядку.

чтобы сделать это с помощью jQuery, вы можете сделать следующее:

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

вот рабочий jsfiddle.

edit - если вы хотите сортировать таким образом, что вы игнорируете алфавитный регистр, вы можете использовать JavaScript .toUpperCase() или .toLowerCase() функции перед сравнением:

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

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

принятый ответ не является лучшим во всех случаях, потому что иногда вы хотите сохранить классы опций и различные аргументы (например, data-foo).

мое решение:

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

//для ie11 или тех, кто получает пустые параметры, замените html (") empty ()

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

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

я использовал решение tracevipin, которое работало фантастически. Я предоставляю немного измененную версию здесь для тех, кто любит находить легко читаемый код и сжимать его после это понятно. Я также использовал .detach вместо .remove для сохранения любых привязок к элементам DOM опции.

вот моя улучшенная версия решение 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);
        }
    }); 
}

функция имеет

The jquery.окна.js плагин имеет метод сортировки. Вы можете реализовать плагин, или погрузиться в код, чтобы увидеть то, что нужным.

ни один из ответов работал для меня. По какой-то странной причине при циклическом просмотре параметров каждый параметр ничего не возвращает, когда text() называется. Вместо этого я был вынужден получить метку опции через 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'));

Это даст вам возможность менять их вручную, Если вам это нужно

как бы вы динамически заказали список

Да вы можете отсортировать параметры по тексту и добавить его обратно в поле выбора.

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

Скрипка: https://jsfiddle.net/vaishali_ravisankar/5zfohf6v/

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

вот плагин jQuery, сделанный из заостренныйответ с помощью 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);
        });
    }
});

использование очень легко

$("select").sortSelect();

Malakgeorge ответ хороший может быть легко обернут в функцию 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;        
}