用于从对象中创建选择元素的Javascript插件

Javascript plugin for creating select elements from an object

本文关键字:元素 Javascript 插件 选择 创建 对象 用于      更新时间:2023-09-26

是否有任何插件,最好是香草,但jquery插件也可以工作,可以将JavaScript对象转换为各自的选择元素

obj = {
    Ford: {
        1: "Focus",
        2: "Fiesta"
    },
    Toyota: {
        1: "Prius",
        2: "Avensis"
    }
}
AwesomePluginMagic(obj);

应该是

<select name="primary">
    <option value="0" selected>Ford</option>
    <option value="1">Toyota</option>
</select>
<select name="secondary">
    <option value="1">Focus</option>
    <option value="2">Fiesta</option>
    <option class="hidden" value="1">Prius</option>
    <option class="hidden" value="2">Avensis</option>
</select>

然后应该监听更改,并在相关的select元素中显示适当的选项。

免责声明:我不希望你为我写一个函数,我要求一个插件已经做了,但如果你坚持我将使用它。此外,输入对象可以是任何格式,我刚刚为示例创建了一个。

关于如何在没有任何库的情况下实现此功能的示例。

(function() {
    'use strict';
    
    var obj = {
        Ford: {            
            1: "Focus",
            2: "Fiesta"            
        },
        Toyota: {            
            1: "Prius",
            2: "Avensis"            
        }
    };
    
    var manufacturers = Object.keys(obj);
    var selectedManufacturer = manufacturers[0];
    var models = hashTokeyValuePairArray(obj[selectedManufacturer]);
    var selectedModel = models[0];
    var selectedCar = { make: selectedManufacturer, model: selectedModel.value };
    bindManufacturer();
    bindModel();    
    bindSelectedCar();
    
    function hashTokeyValuePairArray(o) {
        var k = Object.keys(o);        
        return k.map(function(k) { return { key: k, value: o[k] }; });
    }
    
    function bindSelectedMake() {
        var el = document.getElementById("selectedMake");
        el.innerText = selectedManufacturer;
    }
    
    function bindSelectedModel() {
        var el = document.getElementById("selectedModel");
        el.innerText = selectedModel.value;
    }
    function bindSelectedCar() {
        bindSelectedMake();
        bindSelectedModel();
        
        selectedCar = { make: selectedManufacturer, model: selectedModel.value };
        console.log(selectedCar);
    }
    
    function bindManufacturer() {
        var el = document.getElementById("make");    
        var opts = manufacturers.map(function(m) { return "<option>" + m + "</option>"; });     
        el.innerHTML = opts.join('');        
        el.options.selectedIndex = 0;
        el.addEventListener('change', function() {
            selectedManufacturer = manufacturers[this.options.selectedIndex];
            models = hashTokeyValuePairArray(obj[selectedManufacturer]);
            selectedModel = models[0];
            bindModel(true);
            bindSelectedCar();
        });
    }
    
    function bindModel(skipEventBinding) {
        var el = document.getElementById("model");
        var opts = models.map(function(m) { return "<option value='"" + m.key + "'">" + m.value + "</option>"; });
        el.innerHTML = opts.join('');
        el.options.selectedIndex = 0;
        
        if (!skipEventBinding) {
            el.addEventListener('change', function() {
                selectedModel = models[this.options.selectedIndex];
                bindSelectedCar();
            });
        }
    }
}());
#make, #model { width: 100px; margin-bottom:5px }
<label for="make">Make:</label> <select id="make"></select>
<label for="model">Model:</label> <select id="model">
</select>
<div>
    Selected Car: <span id="selectedMake"></span> <span id="selectedModel"></span>
</div>

向辅助选项添加了一个data-car值,以便它们对主select有一个引用。还为主选项添加了一个change侦听器,它根据所选项目更改辅助选项的.hidden

免责声明:它将与当前格式工作,如果obj有不同的格式需要修改。但我认为这是不可能的,除非对给定对象的格式设置了一些限制。

function AwesomePluginMagic(obj) {
    var prm = document.createElement('select');
    var scnd = document.createElement('select');
    prm.name = "primary";
    scnd.name = "secondary";
    var i = 1;
    for(var itm in obj) {
        var popt = document.createElement('option');
        popt.value = i;
        popt.innerHTML = itm;
        prm.appendChild(popt);
        var j = 1;
        for(var sub in obj[itm]) {
            var sopt = document.createElement('option');
            sopt.setAttribute('data-car', i);
            sopt.value = j;
            sopt.innerHTML = obj[itm][sub];
            if(i > 1)
                sopt.className = "hidden";
            scnd.appendChild(sopt);
            j++;
        }
        i++;
    }
    var dv = document.getElementById('dv');
    dv.appendChild(prm);
    dv.appendChild(scnd);
    prm.addEventListener('change', function() {
        var selected = false;
        var o = scnd.options;
        for(var i = 0; i < o.length; i++) {
            if(o[i].getAttribute('data-car') == this.value) {
                o[i].className =  "";
                if(!selected) {
                    o[i].setAttribute('selected', 'selected');
                    selected = true;
                }
            }
            else
                o[i].className = "hidden";
        }
    });
}
<<p> jsfiddle演示/strong>

JS是面向对象的,为什么不使用对象,像这样:

var // Data
    cars = {
        Ford: {
            1: "Focus",
            2: "Fiesta",
        },
        Toyota: {
            1: "Prius",
            2: "Avensis"
        }
    },
    // The AwesomePlugin
    selectPair = Object.create({}, {
        update: {value: function (select, obj) {
            var keys = Object.keys(obj).sort(function (a, b) {return a.localeCompare(b);}),
                n, eN, option, element = this[select] || document.createElement('select');
            element.length = 0;
            for (n = 0, eN = keys.length; n < eN; n ++) {
                option = document.createElement('option');
                option.text = (typeof obj[keys[n]] === 'object') ? keys[n] : obj[keys[n]];
                option.value = (typeof obj[keys[n]] === 'object') ? keys[n] : obj[keys[n]];
                element.appendChild(option);
            }
            return element;
        }},
        init: {value: function (obj, target) {
            var that = this, keys = Object.keys(obj).sort(function (a, b) {return a.localeCompare(b);});
            this.host = target.appendChild(this.update('host', obj));
            this.child = target.appendChild(this.update('child', obj[keys[0]]));
            this.host.addEventListener('change', function () {
                that.update('child', obj[that.host.value]);
            });
            return this;
        }}
     });
// Usage
Object.create(selectPair).init(cars, document.body);

原型是可重用的,您可以通过使用selectPair原型创建一个新对象并传递所需的数据对象和元素来附加select元素来创建多个"选择对"。