jQuery를 사용하여 옵션 요소를 알파벳순으로 정렬


78

option요소 내에서 select요소를 알파벳순으로 정렬하는 것을 이해하려고합니다 . 이상적으로는 사용자가 일부 버튼을 클릭 할 때 정렬해야하기 때문에 select 요소를 전달할 수있는 별도의 함수로 사용하고 싶습니다.

나는 이것을하는 좋은 방법을 찾기 위해 높고 낮은 것을 검색했지만 나를 위해 일하는 것을 찾을 수 없었습니다.

옵션 요소는 값이 아닌 텍스트를 기준으로 알파벳순으로 정렬되어야합니다.

어떤 식 으로든 가능합니까?


따라서 기본적으로 선택자를 제공하고 포함 된 텍스트에 따라 모든 자녀를 알파벳순으로 정렬하고 싶습니까?
— pkurek 2012-08-22

: 나는 당신이이 주제에 볼해야한다고 생각 stackoverflow.com/questions/1134976/...
— KAZ

@pkurek : 모든 것이 단순합니다. 그렇습니다. :-) kaz : 그래, 나는 그 스 니펫을 가지고 장난을 쳤지 만 단순히 작동하게 할 수 없습니다. :-/ 다른 방법이 있는지 궁금합니다.
— bomortensen 2012-08-22

@bomortensen : 모든 솔루션은 본질적으로 유사합니다. 이 대답 은 가능한 한 쉽습니다.
— Felix Kling 2012-08-22

답변:


123

내가 할 일은 :

  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입니다.

편집 — 알파벳 대소 문자를 무시하도록 정렬하려면 비교하기 전에 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;
});

이것은 나를 위해 해냈다! >와 <을 모두 대문자로 확인해야했습니다. :-) 고마워요 !!
— bomortensen

아 그래 맞다. 알파벳 대소 문자를 무시하고 싶다면 그래. 효과가있어서 다행입니다!
— Pointy 2012-08-22

네, JS는 분류 할 때 대문자의 무게가 소문자보다 높기 때문에 .. 그러니까 ;-) 다시 한번 감사합니다. 매력처럼 작동합니다!
— bomortensen

6
이 답변에 감사드립니다-내 문제를 거의 완전히 해결했습니다. 선택한 옵션을 추적하기 위해이를 보강해야했습니다. arr options.map의 경우 "s : $ (o) .attr ( 'selected')"를 추가 한 다음 options.each에 다음을 추가해야합니다. $ (o) .attr ( 'selected', arr [i] .에스); 감사!
— alexleonard

3
여기에 현재 선택한 옵션을 기억하는 수정 된 코드는 다음과 같습니다 jsfiddle.net/trELD/700
— 제이미 바커

59

때로는 옵션 클래스와 다른 인수 (예 : 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 ()


4
최고의 답변입니다. 제 경우입니다. 옵션 데이터 속성을 유지해야합니다
— Vitor Almeida 2014

쉽고 간단한 답변.
— UdayKiran Pulipati

3
마지막 줄에서 sel.html ( ''). append (opts_list)를 간단히 sel.html (opts_list)로 변경할 수 있습니다
— jbyrd

1
ie (11)에서는 작동하지 않습니다. 옵션의 레이블이 사라집니다. 내가 찾은 가장 크로스 브라우저 솔루션은 jquery-less 솔루션 입니다.
— Cethy 2015-07-29

이것은 정답이되어야합니다! 이것은 위보다 훨씬 간단하며 모든 클래스 또는 데이터 속성을 유지합니다.
— Greg Blass

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

2
$("#mSelect").append($options);:) 충분합니다
— 펠릭스 클링에게

에 대한 콜백 .sort()은 순서 관계를 반영하기 위해 0보다 작거나, 0 또는 더 큰 숫자를 반환해야합니다. 부울을 반환하는 것은 실제로 제대로 작동하지 않을 것이라고 생각합니다.
— Pointy

5
나는 위와 같이 갔다. var at = $ (a) .text (). toLowerCase (), bt = $ (b) .text (). toLowerCase (); 정렬의 경우 독립적으로 만들려면
— JayCrossler

27

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의 솔루션을 사용했습니다. 나는 쉽게 읽을 수있는 코드를 찾는 것을 좋아하는 나와 같은 사람을 위해 약간 수정 된 버전을 제공하고 이해 한 후에 압축합니다 . 또한 옵션 DOM 요소에 대한 바인딩을 유지 하는 .detach대신 사용 했습니다 .remove.


완벽하게 나를 위해 일한
— 훌리오 Popócatl

이것은 최고의 솔루션 IMO이며 요소의 상태를 보존하기 때문에 게시하려는 내용과 매우 유사합니다 (여러 선택에 대해서도).
— Kris Oye

나에게도 완벽하게 작동합니다.
— Hughsie28

4
거의 완벽하지만 Chrome과 Firefox는 마지막 옵션을 선택한대로 표시합니다.
— Cristiano Maia

6

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

이 함수에는 skip_first매개 변수가 있습니다. 이는 첫 번째 옵션을 맨 위에 유지하려는 경우에 유용합니다 (예 : "아래 선택 :").

또한 이전에 선택한 옵션을 추적합니다.

사용 예 :

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

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

});

6

나는이 주제가 오래되었다는 것을 알고 있지만 내 대답은 많은 사람들에게 유용 할 것이라고 생각합니다.

다음은 ES6를 사용하여 Pointy 의 답변으로 만든 jQuery 플러그인입니다 .

/**
 * 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();

2

대답 중 어느 것도 나를 위해 일하지 않았습니다. 이상한 이유로 옵션을 반복 할 때 각 옵션 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'));


1

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

좋은 솔루션이지만 IE11에서는 작동하지 않습니다. 이 기능을 드롭 다운 목록에 적용하면 옵션의 텍스트가 비어 있습니다. .html ( '')을 .empty ()로 바꾸면 작동합니다.
— 무 케시 쿠마르


0

I에서 결합 부품 marxin의 및 kuxa의 훌륭한 대답은 jQuery를 사용자 지정 기능이를 만들려면

  1. 텍스트 값 (대소 문자 구분 안함)별로 옵션을 정렬합니다.

  2. 이미 선택된 값을 유지 하고

  3. 함수가 실행되는 원래 jQuery 객체를 반환합니다.

    $.fn.extend({
        sortSelect() {
            return this.each(function(){
                let $this = $(this),
                    original_selection = $this.val(),
                    $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);
                });
    
                $this.val(original_selection); 
            })
        }
    });
    

jsFiddle의 작업 예제는 https://jsfiddle.net/jhfrench/64och25e/에서 사용할 수 있습니다 .


이 Q / A를 통해 다른 사람에게 도움이되는 방식으로 답변을 강화하여 저를 구한 시간을 활용할 수 있다는 점이 마음에 듭니다. 비바 스택 오버플로 !!!
— Jeromy French
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.