【问题标题】:populate a second drop down menu depends upon first drop down selection填充第二个下拉菜单取决于第一个下拉选择
【发布时间】:2014-01-03 19:01:08
【问题描述】:

我在这里尝试创建 html 下拉列表。我在主列表mobilelaptop 上有两件事要选择。如果我在第一个列表中选择移动选项,则第二个下拉列表必须从移动品牌加载选项。如果我选择笔记本电脑,它必须加载笔记本电脑品牌。现在必须填充第三个列表取决于第二个列表选择。假设如果我选择三星作为移动品牌,它必须在下一个下拉菜单中加载 android 版本。

我的代码(我在此处添加了第二个菜单列表,并在此处使用相同的 ID。)

<select id="main_list">
    <option value="default" selected>Select Your List</option>
    <option value="mobile">mobile list</option>
    <option value="laptop">laptop list</option>
</select>
<select id="brands">
    <option value="default" selected>Select Your Mobile Brand</option>
    <option value="mobile_1">Samsung</option>
    <option value="mobile_2">Nokia</option>
</select>
<select id="brands">
    <option value="default" selected>Select Your Laptop Brand</option>
    <option value="laptop_1">HP</option>
    <option value="laptop_2">Dell</option>
</select>
<select id="samsung_select">
    <option value="default" selected>Select Your Andriod Version</option>
    <option value="andriod_1">4.1</option>
    <option value="andriod_2">4.2</option>
</select>
<select id="nokia_select">
    <option value="default" selected>Select Your Windows Version</option>
    <option value="windows_1">windows 8</option>
    <option value="windows_2">windows 8.1</option>
</select>

自动填充此列表的最佳方式是什么。此处不使用任何数据库。

JSFIDDLE

我之前看过一个类似的问题here,但这对我不起作用

【问题讨论】:

标签: javascript jquery html drop-down-menu


【解决方案1】:

这是一个有点乏味的编码,这是无可避免的,但这应该会给你一个好的开始:

jsFiddle Demo

HTML:

<select id="main_list">
    <option value="default" selected>Select Your List</option>
    <option value="mobile">mobile list</option>
    <option value="laptop">laptop list</option>
</select>
<select id="brand" class="secondary"></select>
<select id="version" class="secondary"></select>

css:

.secondary {display:none;}

js/jQuery:

$(function() {
    var sel, i,
        list = ['mobile', 'laptop'],
        phone = ['Samsung', 'Nokia'],
        laptop = ['HP', 'Dell'],
        android = ['4.1', '4.2'],
        windows = ['8', '8.1'],
        dev_default = '<option value="default" selected>Select your Device brand</option>',
        os_default  = '<option value="default" selected>Select your OS version</option>';

    sel_brand = $('#brand');
    sel_version = $('#version');

    $('select').change(function() {
        switch (this.id) {
            case 'main_list':
                $('.secondary').hide();
                sel_brand.find('option').remove();
                sel_brand.append(dev_default);
                sel_brand.show();
                if (this.value == 'mobile') {
                    for (i = 0; i < phone.length; i++) {
                        $("#brand").append(
                            '<option value="' + phone[i] + '">' + phone[i] + '</option>'
                        );
                    }
                }else if (this.value == 'laptop') {
                    for (i = 0; i < phone.length; i++) {
                        $("#brand").append(
                            '<option value="' + laptop[i] + '">' + laptop[i] + '</option>'
                        );
                    }
                }
                break;
            case 'brand':
                sel_version.find('option').remove();
                sel_version.append(os_default);
                sel_version.show();
                if (this.value == 'Samsung') {
                    for (i = 0; i < android.length; i++) {
                        $("#version").append(
                            '<option value="' + android[i] + '">' + android[i] + '</option>'
                        );
                    }
                }else if (this.value == 'Nokia' || this.value == 'HP' || this.value == 'Dell') {
                    for (i = 0; i < windows.length; i++) {
                        $("#version").append(
                            '<option value="' + windows[i] + '">' + windows[i] + '</option>'
                        );
                    }
                }
                break;
        }
    });

}); //END document.ready()

【讨论】:

    【解决方案2】:

    你是对的。有很多类似的问题,但它们之间似乎总是没有什么区别。

    我以前写过这样的小部件。这是一种与gibberishanswer 完全不同的方法。

    它涉及一个您可以像这样使用的小部件:

    var widget = new DropdownWidget(options);
    widget.onComplete(function(vals) {
        console.log(vals);    
    });
    widget.addTo(document.body);
    

    提供给onComplete 的处理程序将接收对象,例如

    {
        "main_list": "mobile list",
        "brands": "Samsung",
        "samsung_select": "4.2"
    }
    

    您根本不会使用任何标记。相反,它将配置一个像这样的对象:

    var options = [
        {
            id: 1, 
            name: "main_list", 
            defaultVal: "Select Your List", 
            choices: [
                {value: "mobile", text: "mobile list", nextId: 2},
                {value: "laptop", text: "laptop list", nextId: 3}
            ]
        },
        {
            id: 2, 
            name: "brands", 
            defaultVal: "Select Your Mobile Brand", 
            choices: [
                {value: "mobile_1", text: "Samsung", nextId: 4},
                {value: "mobile_2", text: "Nokia", nextId: 5}
            ]
        },
        {
            id: 3, 
            name: "brands", 
            defaultVal: "Select Your Laptop Brand", 
            choices: [
                {value: "laptop_1", text: "HP"},
                {value: "laptop_2", text: "Dell"}
            ]
        },
        {
            id: 4, 
            name: "samsung_select", 
            defaultVal: "Select Your Andriod Version", 
            choices: [
                {value: "android_1", text: "4.1"},
                {value: "android_2", text: "4.2"}
            ]
        },
        {
            id: 5, 
            name: "nokia_select", 
            defaultVal: "Select Your Windows Version", 
            choices: [
                {value: "windows_1", text: "windows 8"},
                {value: "windows_2", text: "windows 8.1"}
            ]
        }
    ];
    

    请注意,如果您不使用重复的名称,这可能会有所不同。 ids 可以被删除,nextId 可以变成nextName

    这是这样一个小部件的幼稚实现:

    var DropdownWidget = (function() {
        var DropdownWidget = function(options) {
            // TODO: type-checking on options: should be array of acceptable configurations...
            this.options = options;
            this.selectedVals = [];
            this.showing = false;
            this.handlers = [];
        };
        DropdownWidget.prototype.onComplete = function(handler) {
            this.handlers.push(handler);    
        };
        DropdownWidget.prototype.addTo = function(element) {
            if (this.showing) {
                alert("Oops!");  // TODO: real error handling, or should this be moveable?
                return;
            }
            var dropdown = createDropdown(this.options[0]);
            this.elements = [dropdown];
            addHandlers(this, dropdown, options, 0);
            element.appendChild(dropdown);
        };
        var createDropdown = function(config) {
            var select = document.createElement("SELECT");
            select.name = config.name;
            select.options[select.options.length] = new Option(config.defaultVal, "default");
            config.choices.forEach(function(choice) {
                select.options[select.options.length] = new Option(choice.text, choice.value);
            });
            return select;
        };
        var addHandlers = function(widget, select, options, index) {
            select.onchange = function() {
                removeSubsequentSelects(widget, options, index);
                if (this.selectedIndex > 0) {
                    var choice = options[index].choices[this.selectedIndex - 1];
                    if (widget.selectedVals[widget.selectedVals.length - 1] !== options[index]) {
                        widget.selectedVals.push(options[index]);
                    }
                    if (choice.nextId) {
                        var nextIndex = findIndex(function(item) {
                            return item.id === choice.nextId;
                        }, options);
                        if (nextIndex > -1) {
                            var dropdown = createDropdown(options[nextIndex]);
                            widget.elements.push(dropdown);
                            addHandlers(widget, dropdown, options, nextIndex);
                            this.parentNode.appendChild(dropdown);
                        }
                    } else {
                        complete(widget);
                    }
                }
            }
        };
        var removeSubsequentSelects = function(widget, options, index) {
            var start = findIndex(function(selected) {
                return selected == options[index];
            }, widget.selectedVals);
            var idx = start;
            if (idx > -1) {
                while (++idx < widget.elements.length) {
                    widget.elements[idx].parentNode.removeChild(widget.elements[idx]);
                }
                widget.elements.length = widget.selectedVals.length = start + 1;
            }
        }
    
        var findIndex = function(predicate, list) {
            var idx = -1;
            while (++idx < list.length) {if (predicate(list[idx])) {return idx;}}
            return -1;
        };
    
        var complete = function(widget) {
            var vals = widget.selectedVals.map(function(val, idx) {
                return {name: val.name, val: val.choices[widget.elements[idx].selectedIndex - 1].text}
            }).reduce(function(memo, obj) {memo[obj.name] = obj.val; return memo;}, {});
            widget.handlers.forEach(function(handler) {
                handler(vals);
            });
        };
    
        return DropdownWidget;
    }());
    

    您可以在 JSFiddle 上看到它的实际效果。

    有很多事情可以做得更好。我看到的最大问题是构造的 SELECTS 的 DOM 位置非常简单。

    无论如何,这是一种不同的方法。

    【讨论】:

      猜你喜欢
      • 2021-12-11
      • 2021-09-30
      • 2023-03-14
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多