javascript 排序下拉列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18327985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 11:30:37  来源:igfitidea点击:

Sort dropdown list

javascripthtmlhtml-select

提问by abbisDK

I am trying to sort a dropdownlist (selector) in html.

我正在尝试在 html 中对下拉列表(选择器)进行排序。

I have two lists, a pre-selection which then should be used to define the content of the secont list.

我有两个列表,一个预选,然后应该用于定义第二个列表的内容。

A short code sample:

一个简短的代码示例:

<!doctype html>
<html class="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>
<table width=100% border="0">
  <tr>
  <td>&nbsp;</td>
    <td>Product</td>
    <td><select name="product" id="product" width="300" style="width: 300px">
      <option></option>
      <option id="TLX">TLX</option>
      <option id="FLX">FLX</option>
      <option id="MLX">MLX</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
  <tr>
  <td>&nbsp;</td>
    <td>Power</td>
    <td><select name="power" id="power" width="300" style="width: 300px">
      <option></option>
      <option name="TLX">6</option>
      <option name="TLX">8</option>
      <option name="TLX">10</option>
      <option name="TLX">12</option>
      <option name="TLX">15</option>
      <option name="FLX">6</option>
      <option name="FLX">8</option>
      <option name="FLX">10</option>
      <option name="FLX">12</option>
      <option name="FLX">15</option>
      <option name="FLX">17</option>
      <option name="MLX">30</option>
      <option name="MLX">40</option>
      <option name="MLX">60</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
</table>

</body>
</html>

I want to b able to select the product and then must the power list be sortet accordingly.

我希望能够选择产品,然后必须相应地对电源列表进行排序。

For instance if TLX is choosen then only 6, 8, 10, 12, and 15 are shown as possibilities in the second list.

例如,如果选择了 TLX,则在第二个列表中仅显示 6、8、10、12 和 15 作为可能性。

回答by dc5

No attempt was made to be cross browser here… But there's only one browser I can think of that might give you trouble :)

这里没有尝试跨浏览器......但我能想到的只有一种浏览器可能会给你带来麻烦:)

Demo

演示

Code

代码

var product = document.getElementById('product');
var power   = document.getElementById('power');
var allOpts = power.getElementsByTagName('option');
var opts = {
    empty: allOpts[0]
};

// This builds three additional lists of options for each type of product
// It relies on having a single attribute - if more are added, this logic
// would need to be adjusted.
for(var i = 1; i < allOpts.length; ++i) {
    var name = allOpts[i].attributes[0].value;

    opts[name] = opts[name] || [];
    opts[name].push(allOpts[i]);
}

// Each time product is changed, just loop through based on the selected ID
// and add those options to the power select list (removing all children first)
product.addEventListener('change', function(evt) {
    var val = evt.target.value;

    power.innerHTML = '';
    power.appendChild(opts.empty);
    for(var i = 0; i < opts[val].length; ++i) {
        power.appendChild(opts[val][i]);
    }
});

Here is a version using documentFragment:

这是一个使用 documentFragment 的版本:

Demo

演示

documentFragment version

文档片段版本

var product = document.getElementById('product');
var power   = document.getElementById('power');
var allOpts = power.getElementsByTagName('option');
var opts = {
    empty: allOpts[0]
};

// Appending to the doc fragment removes it from the live nodelist
while(allOpts.length > 1) {
    var name = allOpts[1].attributes[0].value;

    opts[name] = opts[name] || document.createDocumentFragment();
    opts[name].appendChild(allOpts[1]);
}

product.addEventListener('change', function(evt) {
    var val = evt.target.value;

    power.innerHTML = '';
    power.appendChild(opts.empty);
    power.appendChild(opts[val].cloneNode(true));
});

Update

更新

With just a little more work, this can be made more generic - say when new requirements come in comments to the original answer :)

只需多做一点工作,就可以使这更通用——比如当新需求出现在对原始答案的评论中时 :)

Additional requirements

其他要求

Note: I added the empty option element to keep the solution simpler. The code can be adapted to handle the absence of it as well, but that will be left as an exercise for the reader.

注意:我添加了空的 option 元素以使解决方案更简单。该代码也可以进行调整以处理它的缺失,但这将留给读者作为练习。

<select name="continent" id="continent">'
    <option value="IMAGES/maps/europe_gray.png" id="EU">Europe</option>
    <option value="IMAGES/maps/europe_gray.png" id="AS">Asia</option>
</select>
<select name="country" id="country">
    <option></option>
    <option name="EU" id="ALB" value="IMAGES/flags/al.png">Albania, Republic of</option>
    <option name="AS" id="RUS" value="IMAGES/flags/ru.png">Russia</option>
</select>

With the changes below, the controller logic is now more generic in that it can adapt to the markup by accepting additional information that tells it where to find its keys and select elements.

通过下面的更改,控制器逻辑现在更加通用,因为它可以通过接受附加信息来适应标记,这些信息告诉它在哪里可以找到它的键和选择元素。

Generic Controller Example

通用控制器示例

/* params {
 *    master: id of the master select element
 *    subord: id of the subordinate select element
 *    mKey:   name of the attribute holding the key in master that will be used to filter subordinate options
 *    sKey:   name of the attribute in subordinate that will be used to match against mKey
 */
function selectController(params) {
    var master = document.getElementById(params.master);
    var subord = document.getElementById(params.subord);
    var allOpts = subord.getElementsByTagName('option');
    var opts = {
        empty: allOpts[0]
    };

    // Appending to the doc fragment removes it from the live nodelist
    while (allOpts.length > 1) {
        var name = allOpts[1].getAttribute(params.sKey);

        opts[name] = opts[name] || document.createDocumentFragment();
        opts[name].appendChild(allOpts[1]);
    }

    master.addEventListener('change', function (evt) {
        var sel  = master.options[master.selectedIndex];
        var mKey = sel.getAttribute(params.mKey); 

        subord.innerHTML = '';
        subord.appendChild(opts.empty);
        subord.appendChild(opts[mKey].cloneNode(true));
    });
}

selectController({
    master: 'product',
    subord: 'power',
    mKey:   'id',
    sKey:   'name'
});

selectController({
    master: 'continent',
    subord: 'country',
    mKey:   'id',
    sKey:   'name'
});

回答by Luan Castro

using vanilla you can do like below

使用香草你可以像下面这样

see the demo working http://jsfiddle.net/ST5dq/

查看演示工作http://jsfiddle.net/ST5dq/

no use name attribute, use data-name, value or other attribute, the name attribute not working cross browser to option tag...

不使用名称属性,使用数据名称,值或其他属性,名称属性不能跨浏览器工作到选项标签...

i'll use data-name

我将使用数据名称

<table width=100% border="0">
  <tr>
  <td>&nbsp;</td>
    <td>Product</td>
    <td><select name="product" id="product" width="300" style="width: 300px">
      <option></option>
      <option id="TLX">TLX</option>
      <option id="FLX">FLX</option>
      <option id="MLX">MLX</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
  <tr>
  <td>&nbsp;</td>
    <td>Power</td>
    <td><select name="power" id="power" width="300" style="width: 300px">
      <option></option>
      <option data-name="TLX">6</option>
      <option data-name="TLX">8</option>
      <option data-name="TLX">10</option>
      <option data-name="TLX">12</option>
      <option data-name="TLX">15</option>
      <option data-name="FLX">6</option>
      <option data-name="FLX">8</option>
      <option data-name="FLX">10</option>
      <option data-name="FLX">12</option>
      <option data-name="FLX">15</option>
      <option data-name="FLX">17</option>
      <option data-name="MLX">30</option>
      <option data-name="MLX">40</option>
      <option data-name="MLX">60</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
</table>

you can use this to sort the list

您可以使用它对列表进行排序

function sortDropdownList(ddl){

    var options = [].slice.apply(ddl.options, [0]);
    ddl.innerHTML = "";
    var sorted = options.sort(function(a,b){     
       return +(a.innerText) - +(b.innerText);
    });

    for(var i = 0; i < sorted.length; i++){
      ddl.options.add(sorted[i]);
    }  

}

you need pass a dom element, not a jQuery element.

您需要传递一个 dom 元素,而不是一个 jQuery 元素。

to bind the select parent to select child you can do this

将选择的父项绑定到选择的子项,您可以执行此操作

on you page initialize add the code

在您的页面初始化添加代码

var parentSelect = document.getElementById("product");
var childSelect = document.getElementById("power");
var options = [].slice.apply(childSelect, [0]);
var emptyOption = options[0];
childSelect.innerHTML = "";

parentSelect.addEventListener("change", function(e){

    var selectedId = parentSelect.options[parentSelect.selectedIndex].id;
    childSelect.innerHTML = "";
    childSelect.options.add(emptyOption);
    for(var i = 0; i < options.length; i++){

        if( options[i].getAttribute("data-name") == selectedId ){

           childSelect.options.add(options[i]);

        }
    }

    sortDropdownList(childSelect);

});

回答by user2668376

If you are using jquery, can be accomplished like so: Demo

如果你使用jquery,可以这样完成:Demo

$(document).ready(function(){    
    var powerOptions = $('#power option').hide();
    $('#product').change(function(){
        powerOptions.hide().filter('option[name=' + $(this).find('option:selected').val() + ']').show();
    });
});

Note: In product dropdown, change id attribute of each option to name.

注意:在产品下拉菜单中,将每个选项的 id 属性更改为 name。

回答by Elvin Mammadov

You need cascading dropdownlist

您需要级联下拉列表

Please look at this links:

请看这个链接:

And you can find other links about cascading dropdownlists from google search or other...

您可以从谷歌搜索或其他网站找到有关级联下拉列表的其他链接...