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.