Javascript来对select元素的内容进行排序

时间:2008-11-10 15:09:57

标签: 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>

21 个答案:

答案 0 :(得分:63)

这样就可以了。当您需要对列表进行排序时,只需将选择元素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;
}

答案 1 :(得分:37)

这个解决方案对我使用jquery工作非常好,以为我在这里交叉引用它,因为我在另一个之前找到了这个页面。其他人可能会这样做。

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

来自Sorting dropdown list using Javascript

答案 2 :(得分:3)

来自W3C FAQ

  

尽管许多编程语言都有类似下拉框的设备,它们能够在将项目列表作为其功能的一部分进行显示之前对项目列表进行排序,但HTML&lt; select&gt;功能没有这样的能力。它列出了&lt; options&gt;按收到的顺序。

您必须手动为静态HTML文档排序,或者使用Javascript或其他一些动态文档的编程排序。

答案 3 :(得分:3)

另一种选择:

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

答案 4 :(得分:3)

我遇到了同样的问题。这是我提出的 jQuery解决方案

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

答案 5 :(得分:2)

使用Marco Lazzeri和Terre Porter提供的答案(如果这个答案有用,请将其投票),我想出了一个稍微不同的解决方案,它保留了所选的值(可能不会保留事件处理程序或附加数据,虽然)使用 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);

答案 6 :(得分:2)

这是我在这个主板上最喜欢的3个答案的重新汇编:

  • jOk最好最简单的答案。
  • Terry Porter简单的jQuery方法。
  • SmokeyPHP的可配置功能。<​​/ li>

结果是易于使用且易于配置的功能。

第一个参数可以是选择对象,选择对象的ID或至少具有2个维度的数组。

第二个参数是可选的。默认为按选项文本排序,索引0.可以传递任何其他索引,以便对其进行排序。可以传递1或文本“value”,按值排序。

按文字示例排序(全部按文字排序):

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

答案 7 :(得分:1)

是的,DOK有正确的答案......要么在编写HTML之前对结果进行预排序(假设它是动态的,你负责输出),或者你写了javascript。

Javascript Sort方法将成为您的朋友。只需将值从选择列表中拉出,然后对其进行排序,然后将其放回: - )

答案 8 :(得分:1)

Í认为这是一个更好的选择(我使用@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;
        }

答案 9 :(得分:1)

我使用了这种冒泡排序,因为我无法通过options数组中的.value对它们进行排序,而且它是一个数字。这样我就得到了正确的订购。我希望它对你也有用。

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

答案 10 :(得分:1)

我有一个类似的问题,除了我希望所选项目显示在顶部,我不想清除选择了哪些项目(多选列表)。我的基于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);
}

答案 11 :(得分:1)

我很快就把一个允许选择方向(“asc”或“desc”)的方法放在一起,是否应该对选项值(true或false)进行比较,以及是否应该使用前导和尾随空格在比较之前修剪(布尔)。

此方法的好处是保留所选的选项,并且还应保留所有其他特殊属性/触发器。

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

答案 12 :(得分: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
})

但是,对于Alpha / Numeric下拉列表:

灵感来自: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 example Second example

答案 13 :(得分:1)

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值以避免覆盖,对数组进行排序,然后将排序后的数组推回到选择框中

答案 14 :(得分:0)

我认为我的函数对于字符串或数字更通用,并且不会对第一个元素进行排序(如果它可能意味着全部)。

/** Check if a string can be parsed as a number. */
function isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) };

/** Sort options of HTML elements. */
function sortOptions(selectElement, exceptFirstOpt=false) {

    // List of options.
    var options = selectElement.options;
    // If empty list, do nothing.
    if(!options || options.length==0) return;

    // Array.
    var optionsArray = [];
    for (var i = (exceptFirstOpt ? 1 : 0); i < options.length; i++)
        optionsArray.push(options[i]);
    // Sort.
    optionsArray = optionsArray.sort(function (a, b) {      
        let v1 = a.innerHTML.toLowerCase();
        let v2 = b.innerHTML.toLowerCase();
        if((v1==undefined || v1 == '') && (v2==undefined || v2 == ''))
            return 0;
        else if(v1==undefined || v1.trim() == '') return 1;
        else if(v2==undefined || v2.trim() == '') return -1;

        // If number.
        if(isNumber(v1) && isNumber(v2))
            return parseFloat(v1)>parseFloat(v2);

        return v1.localeCompare(v2);   
    });

    // Update options.
    for (var i = 0; i <= optionsArray.length; i++)            
        options[i + (exceptFirstOpt ? 1 : 0)] = optionsArray[i];
    // First option selected by default.
    options[0].selected = true;
}

答案 15 :(得分:0)

对于那些希望排序是否有optgroup的人:

/**
 * Sorting options 
 * and optgroups
 * 
 * @param selElem select element
 * @param optionBeforeGroup ?bool if null ignores, if true option appear before group else option appear after group
 */
function sortSelect(selElem, optionBeforeGroup = null) {
    let initialValue = selElem.tagName === "SELECT" ? selElem.value : null; 
    let allChildrens = Array.prototype.slice.call(selElem.childNodes);
    let childrens = [];

    for (let i = 0; i < allChildrens.length; i++) {
        if (allChildrens[i].parentNode === selElem && ["OPTGROUP", "OPTION"].includes(allChildrens[i].tagName||"")) {
            if (allChildrens[i].tagName == "OPTGROUP") {
                sortSelect(allChildrens[i]);
            }
            childrens.push(allChildrens[i]);
        }
    }

    childrens.sort(function(a, b){
        let x = a.tagName == "OPTGROUP" ? a.getAttribute("label") : a.innerHTML;
        let y = b.tagName == "OPTGROUP" ? b.getAttribute("label") : b.innerHTML;
        x = typeof x === "undefined" || x === null ? "" : (x+"");
        y = typeof y === "undefined" || y === null ? "" : (y+"");

        if (optionBeforeGroup === null) {
            if (x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
            if (x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
        } else if (optionBeforeGroup === true) {
            if ((a.tagName == "OPTION" && b.tagName == "OPTGROUP") || x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
            if ((a.tagName == "OPTGROUP" && b.tagName == "OPTION") || x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
        } else if (optionBeforeGroup === false) {
            if ((a.tagName == "OPTGROUP" && b.tagName == "OPTION") || x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
            if ((a.tagName == "OPTION" && b.tagName == "OPTGROUP") || x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
        }
        return 0;
    });

    if (optionBeforeGroup !== null) {
        childrens.sort(function(a, b){
            if (optionBeforeGroup === true) {
                if (a.tagName == "OPTION" && b.tagName == "OPTGROUP") {return -1;}
                if (a.tagName == "OPTGROUP" && b.tagName == "OPTION") {return 1;}
            } else {
                if (a.tagName == "OPTGROUP" && b.tagName == "OPTION") {return -1;}
                if (a.tagName == "OPTION" && b.tagName == "OPTGROUP") {return 1;}
            }
            return 0;
        });
    }

    selElem.innerHTML = "";
    for (let i = 0; i < childrens.length; i++) {
        selElem.appendChild(childrens[i]);
    }

    if (selElem.tagName === "SELECT") {
        selElem.value = initialValue;
    }
}

答案 16 :(得分:0)

Vanilla JS es6本地化选项排序示例

SELECT ClaimID
       ,cast(DateClosed AS date) AS DateClosed
       ,count(ClaimID) CountClaimID
       ,count(claimid) OVER ( PARTITION BY Month(DateClosed), year(DateClosed)) AS CountPerMonth
       ,case when DateClosed is null then 0 else count(DateClosed) over () / (select 0.0+count(distinct left(cast(DateClosed as date),7)) from @TestTable) end AS TotalAverage
FROM   @TestTable
GROUP  BY ClaimID,DateClosed

我的用例是使用具有区域设置意识的排序来对国家/地区选择下拉列表进行本地化。这在250多个选项中使用,在我的计算机上非常强大〜10ms

答案 17 :(得分:0)

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

答案 18 :(得分:0)

试试这个...希望它能为您提供解决方案:     

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>

答案 19 :(得分:0)

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

答案 20 :(得分:0)

不像Marco的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); } );
}

然后只传递一个选择元素:

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