वर्तमान में चयनित आइटम को संरक्षित करते हुए, मूल्य के हिसाब से Html Select के विकल्पों को क्रमबद्ध करने का सबसे कुशल तरीका क्या है?


81

मेरे पास jQuery है लेकिन मुझे यकीन नहीं है कि इसमें कोई अंतर्निहित छँटाई सहायक है। मैं प्रत्येक आइटम के एक 2 डी सरणी बना सकता है text, valueऔर selectedगुण है, लेकिन मुझे नहीं लगता कि जावास्क्रिप्ट में बनाया गया है है Array.sort()सही ढंग से काम करेगा।


4
स्वयं पर ध्यान दें (जब से मैं इस प्रश्न को कई बार Google के माध्यम से वापस आया हूं): यहां एक अच्छा समाधान है जो आपने लिखा है: gist.github.com/1072537
ट्रैविस

जवाबों:


135

अस्थायी सरणी में विकल्प निकालें, सॉर्ट करें, फिर सूची का पुनर्निर्माण करें:

var my_options = $("#my_select option");
var selected = $("#my_select").val();

my_options.sort(function(a,b) {
    if (a.text > b.text) return 1;
    if (a.text < b.text) return -1;
    return 0
})

$("#my_select").empty().append( my_options );
$("#my_select").val(selected);

मोज़िला का सॉर्ट डॉक्यूमेंटेशन (विशेषकर तुलना) और विकिपीडिया का सॉर्टिंग एल्गोरिथम पेज प्रासंगिक हैं।

आप प्रकार केस संवेदी बनाना चाहते हैं, की जगह textके साथtext.toLowerCase()

ऊपर दिखाया गया सॉर्ट फ़ंक्शन दिखाता है कि कैसे सॉर्ट करना है। गैर-अंग्रेजी भाषाओं को सही ढंग से क्रमबद्ध करना जटिल हो सकता है ( यूनिकोड कोलाज एल्गोरिथ्म देखें )। सॉर्ट फ़ंक्शन में localeCompare का उपयोग करना एक अच्छा समाधान है, जैसे:

my_options.sort(function(a,b) {
    return a.text.localeCompare(b.text);
});

1
इस प्रश्न पर 3 साल बाद फिर से विचार करना, और यह मार्ग जाने का सही तरीका लगता है
ट्रैविस

8
ध्यान दें कि यह केस-संवेदी है - अर्थात्, यह उन सभी चीजों को छांटेगा, जो अपरकेस अक्षरों से शुरू होती हैं, जो कि लोअरकेस अक्षरों से शुरू होती हैं। यदि यह अवांछनीय है, तो बस .toUpperCase()प्रत्येक के बाद जोड़ दें.text
TJ Ellis

10
इसके अलावा, यह सभी ब्राउज़रों में वर्तमान में चयनित विकल्प को संरक्षित नहीं करेगा जैसा कि है (क्रोम को याद है कि क्या चुना गया था, लेकिन फ़ायरफ़ॉक्स और यानी नहीं किया गया था, और विकल्प पढ़ने के बाद अंतिम तत्व चुना गया था)। इसे ठीक करने के लिए, सॉर्ट करने से पहले मौजूदा चयनित मूल्य को सहेजें, फिर इसे फिर से भरें। यानी, इससे पहले कि कुछ और करते हैं var selected = $("#my_select").val(); और फिर हल किए गए विकल्पों के बाद, घाटी को बहाल करते हैं, अर्थात$("#my_select").val(selected);
TJ Ellis

3
ठंडा। 'और' शब्द हटाए जा सकते हैं। वापसी वैसे भी कार्य करता है।
एलीशेर

केस-संवेदनशीलता के बारे में @TJEllis, इस सवाल क्यों एक का उपयोग करना चाहिए और भी अधिक जानकारी प्रदान करता है .toUpperCase()बनाम .toLowerCase()जब अनदेखी मामलों stackoverflow.com/questions/2140627/...
एड्रियन रहो

20

थोड़ा ऊपर टॉम का जवाब संशोधित किया गया है ताकि यह वास्तव में छांटे गए तत्वों की सामग्री को संशोधित करने के बजाय केवल छांटे गए तत्वों को वापस करने के लिए संशोधित करता है।

$('#your_select_box').sort_select_box();

jQuery फ़ंक्शन:

$.fn.sort_select_box = function(){
    // Get options from select box
    var my_options = $("#" + this.attr('id') + ' option');
    // sort alphabetically
    my_options.sort(function(a,b) {
        if (a.text > b.text) return 1;
        else if (a.text < b.text) return -1;
        else return 0
    })
   //replace with sorted my_options;
   $(this).empty().append( my_options );

   // clearing any selections
   $("#"+this.attr('id')+" option").attr('selected', false);
}

1
यह उत्तर शीर्ष के करीब है, लेकिन सही ढंग से चयन नहीं करता है
यूलहा

18

मैंने मार्क के विचार को एक जॉकरी फ़ंक्शन में लपेटा है

$('#your_select_box').sort_select_box();

JQuery समारोह:

$.fn.sort_select_box = function(){
    var my_options = $("#" + this.attr('id') + ' option');
    my_options.sort(function(a,b) {
        if (a.text > b.text) return 1;
        else if (a.text < b.text) return -1;
        else return 0
    })
   return my_options;
}

मैं इसे अपने वर्तमान क्लिक ईवेंट में कैसे जोड़ सकता हूं? $ ('# addwire')। क्लिक करें (फंक्शन () {return! $ ('# wireselection ऑप्शन, सिलेक्टेड') को हटा दें। काम करने के लिए प्रतीत नहीं होता है
mcgrailm

12

समाधान मैंने अपनी टिप्पणी में @Juan Perez का उल्लेख किया है

$.fn.sortOptions = function(){
    $(this).each(function(){
        var op = $(this).children("option");
        op.sort(function(a, b) {
            return a.text > b.text ? 1 : -1;
        })
        return $(this).empty().append(op);
    });
}

उपयोग:

$("select").sortOptions();

इस पर अभी भी सुधार किया जा सकता है, लेकिन मुझे किसी और घंटी या सीटी को जोड़ने की आवश्यकता नहीं है :)


6

खैर, IE6 में यह नेस्टेड सरणी के [0] आइटम पर सॉर्ट करना प्रतीत होता है:

function sortSelect(selectToSort) {
    var arrOptions = [];

    for (var i = 0; i < selectToSort.options.length; i++)  {
        arrOptions[i] = [];
        arrOptions[i][0] = selectToSort.options[i].value;
        arrOptions[i][1] = selectToSort.options[i].text;
        arrOptions[i][2] = selectToSort.options[i].selected;
    }

    arrOptions.sort();

    for (var i = 0; i < selectToSort.options.length; i++)  {
        selectToSort.options[i].value = arrOptions[i][0];
        selectToSort.options[i].text = arrOptions[i][1];
        selectToSort.options[i].selected = arrOptions[i][2];
    }
}

मैं देखूंगा कि क्या यह अन्य ब्राउज़रों में काम करता है ...

संपादित करें: यह फ़ायरफ़ॉक्स में भी काम करता है, हू हू!

हालांकि इस से एक आसान तरीका है? वहाँ जावास्क्रिप्ट या jQuery में बनाया गया कुछ तरीका है जो कि मुझे याद आ रही है का चयन करता है, या यह सबसे अच्छा तरीका है?


8
ध्यान दें कि यह फ़ंक्शन विकल्प तत्वों को सॉर्ट नहीं करता है ; यह मौजूदा तत्वों पर [मूल्य, पाठ, चयनित] को बदल देता है जैसे कि उन्हें क्रमबद्ध किया जाता है (इस मामले में मूल्य द्वारा)। यह अधिकांश अनुप्रयोगों के लिए पर्याप्त है, लेकिन यदि आपके पास अन्य विशेषताएँ (CSS, टूल टिप्स आदि) हैं, तो यह दृष्टिकोण पर्याप्त नहीं होगा।
NVRAM

6

नहीं है एक बंद jQuery टिकट एक तरह से है कि काम करना चाहिए के लिए, लेकिन सिर्फ कोर में शामिल नहीं किया गया था।

jQuery.fn.sort = function() {
  return this.pushStack( [].sort.apply( this, arguments ), []);
};

Google समूह थ्रेड से संदर्भित , मुझे लगता है कि आप केवल एक फ़ंक्शन में पास करते हैं जिसे सॉर्ट करने के लिए उपयोग किया जाता है, जैसे

function sortSelect(selectToSort) {
    jQuery(selectToSort.options).sort(function(a,b){ 
        return a.value > b.value ? 1 : -1; 
    });
}

आशा है कि इससे सहायता मिलेगी!


1
सॉर्टसेलेट फ़ंक्शन के बारे में कुछ समस्याएँ: यह समान विकल्पों पर विचार नहीं करता है। मूल्य के अनुसार और पाठ नहीं। jQuery की वस्तुओं में "विकल्प" नाम की कोई संपत्ति नहीं है। कोई प्रभाव नहीं पड़ता है, क्योंकि आपको विकल्पों को एक नए चयन तत्व में जोड़ना होगा।
सिमोन

4

यह एक बेहतर उपाय है। JQuery के लिए एक वैश्विक समारोह घोषित करें

$.fn.sortSelect = function() {
    var op = this.children("option");
    op.sort(function(a, b) {
        return a.text > b.text ? 1 : -1;
    })
    return this.empty().append(op);
}

और कोड से फ़ंक्शन को कॉल करें।

$("#my_select").sortSelect();

1
मैंने इस पर एक भिन्नता का उपयोग किया, $ (इस) .each () में आंतरिक भाग को लपेटते हुए ताकि मैं इसे एक से अधिक बार संभालने के लिए चयनकर्ता को पास कर सकूं।
टॉम पीट्रोसांती

1
इसके अलावा, आपको $(this)बस के बजाय उपयोग करने की आवश्यकता हैthis
टॉम पिएत्रोसांटी

2

Array.sort()प्रत्येक तत्व को एक स्ट्रिंग में बदलने और उन मूल्यों की तुलना करने में चूक। तो के ["value", "text", "selected"]रूप में हल हो जाता है "value, text, selected"। जो शायद ठीक काम करेगा, ज्यादातर समय।

यदि आप अकेले मूल्य पर क्रमबद्ध करना चाहते हैं, या संख्या के रूप में मूल्य की व्याख्या करते हैं, तो आप एक तुलना फ़ंक्शन को सॉर्ट () में पास कर सकते हैं:

arrOptions.sort(function(a,b) { return new Number(a[0]) - new Number(b[0]); });

1

याद रखें: यदि आप संदर्भ चयनकर्ता का उपयोग करना चाहते हैं, तो सिर्फ आईडी ही काम नहीं करेगा

$.fn.sort_select_box = function(){
    var my_options = $("option", $(this));
    my_options.sort(function(a,b) {
        if (a.text > b.text) return 1;
        else if (a.text < b.text) return -1;
        else return 0
    });
    $(this).empty().append(my_options);
}

// Usando:
$("select#ProdutoFornecedorId", $($context)).sort_select_box();

1

थोड़ा देर से लेकिन इसके लायक मैं एक और अधिक जटिल कार्य को कार्यान्वित कर चुका हूं आप उदारतापूर्वक शामिल कर सकते हैं। इसमें विभिन्न आउटपुट के लिए कुछ विकल्प हैं। यह <OPTGROUP>उनके लेबल के आधार पर टैग में भी पुनरावृत्ति कर सकता है ।

$.fn.sortSelect = function(options){

    const OPTIONS_DEFAULT = {
        recursive:      true,   // Recurse into <optgroup>
        reverse:        false,  // Reverse order
        useValues:      false,  // Use values instead of text for <option> (<optgruop> is always label based)
        blankFirst:     true,   // Force placeholder <option> with empty value first, ignores reverse
    }

    if (typeof options != "object" || null === options) {
        options = OPTIONS_DEFAULT;
    }

    var sortOptions = function($root, $node, options){

        if ($node.length != 1) {
            return false;
        }

        if ($node[0].tagName != "SELECT" && $node[0].tagName != "OPTGROUP") {
            return false;
        }

        if (options.recursive) {
            $node.children('optgroup').each(function(k, v){
                return sortOptions($root, $(v), options);
            });
        }

        var $options        = $node.children('option, optgroup');
        var $optionsSorted  = $options.sort(function(a, b){

            if (options.blankFirst) {
                if (a.tagName == "OPTION" && a.value == "") {
                    return -1;
                }

                if (b.tagName == "OPTION" && b.value == "") {
                    return 1;
                }
            }

            var textA = (a.tagName == "OPTION" ? (options.useValues ? a.value : a.text) : a.label);
            var textB = (b.tagName == "OPTION" ? (options.useValues ? a.value : b.text) : b.label);

            if (textA > textB) {
                return options.reverse ? -1 : 1;
            }

            if (textA < textB) {
                return options.reverse ? 1 : -1;
            }

            return 0;

        });

        $options.remove();
        $optionsSorted.appendTo($node);

        return true;

    };

    var selected = $(this).val();
    var sorted = sortOptions($(this), $(this), {...OPTIONS_DEFAULT, ...options});
    $(this).val(selected);

    return sorted;

};

फिर आप sortSelect()किसी भी <SELECT>टैग पर फ़ंक्शन को कॉल कर सकते हैं , या <OPTGROUP>केवल एक समूह के विकल्पों को सॉर्ट करने के लिए एक सिंगल कर सकते हैं।

उदाहरण:

$('select').sortSelect();

"रिवर्स" विकल्प का उपयोग करके रिवर्स ऑर्डर करें:

$('select').sortSelect({
    reverse: true
});

आप इसे स्वचालित रूप से सभी चयनों पर लागू कर सकते हैं, केवल तभी जब वे इसमें एक महत्वपूर्ण वर्ग (जैसे "js-sort") शामिल करते हैं:

$('select.js-sort').each(function(k, v){
    $(v).sortSelect();
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.