填充第二个下拉菜单取决于第一个下拉选择

时间:2014-01-03 19:01:09

标签: javascript jquery html drop-down-menu

这里我试图创建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,但这不适合我

2 个答案:

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

答案 1 :(得分:1)

你是对的。有很多类似的问题,但它们之间似乎总是差别不大。

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

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

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

请注意,如果您没有使用重复的名称,这可能会有所不同。可以删除idnextId可以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位置非常简单。

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