Sort dropdown list

纵然是瞬间 提交于 2019-12-04 21:44:08

using vanilla you can do like below

see the demo working 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.

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

});

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:

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.

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

If you are using jquery, can be accomplished like so: 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.

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...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!