代码之家  ›  专栏  ›  技术社区  ›  Jay Corbett

使用javascript和jquery,用数组结构填充相关的选择框

  •  23
  • Jay Corbett  · 技术社区  · 17 年前

    this question ,我已经能够基于对另一个选择框的选择填充一个选择框。( I posted my answer here )从服务器端构建的数组结构中提取数据,该数组结构存储在.js文件中,并在html页面中引用。

    cars : [Honda[Accord[Lx, Dx]], [Civic[2dr, Hatchback]],
       [Toyota[Camry[Blk, Red]], [Prius[2dr,4dr]]
    

    例如:如果选择本田,则下一个选择框将显示[Accord Civic],如果选择雅阁,则下一个选择框将显示[Lx Dx]

    我怎么能

    1) 是否创建一个数组结构来保存数据?以致

    2) 我可以使用一个选择框中的值来引用下一个选择框所需的值

    谢谢

    var cars = [
     {"makes"  : "Honda",
      "models"  : [
        {'Accord' : ["2dr","4dr"]} ,
        {'CRV'  : ["2dr","Hatchback"]} ,
        {'Pilot': ["base","superDuper"] } ]
     },
     {"makes"   :"Toyota",
      "models"  : [
        {'Prius'   : ["green","reallyGreen"]} ,
        {'Camry'   : ["sporty","square"]} ,
        {'Corolla' : ["cheap","superFly"] } ]
     } ] ;              
    
     alert(cars[0].models[0].Accord[0]); ---> 2dr
    
    4 回复  |  直到 9 年前
        1
  •  46
  •   Marko Dumic    17 年前

    我更喜欢这样的数据结构:

    var carMakers = [
        { name: 'Honda', models: [
                { name: 'Accord', features: ['2dr', '4dr'] },
                { name: 'CRV', features: ['2dr', 'Hatchback'] },
                { name: 'Pilot', features: ['base', 'superDuper'] }
            ]},
    
        { name: 'Toyota', models: [
                { name: 'Prius', features: ['green', 'superGreen'] },
                { name: 'Camry', features: ['sporty', 'square'] },
                { name: 'Corolla', features: ['cheap', 'superFly'] }
            ]}
    ];
    

    // returns array of elements whose 'prop' property is 'value'
    function filterByProperty(arr, prop, value) {
        return $.grep(arr, function (item) { return item[prop] == value });
    }
    
    // populates select list from array of items given as objects: { name: 'text', value: 'value' }
    function populateSelect(el, items) {
        el.options.length = 0;
        if (items.length > 0)
            el.options[0] = new Option('please select', '');
    
        $.each(items, function () {
            el.options[el.options.length] = new Option(this.name, this.value);
        });
    }
    
    // initialization
    $(document).ready(function () {
        // populating 1st select list
        populateSelect($('#maker').get(0), $.map(carMakers, function(maker) { return { name: maker.name, value: maker.name} }));
    
        // populating 2nd select list
        $('#maker').bind('change', function() {
            var makerName = this.value,
                carMaker = filterByProperty(carMakers, 'name', makerName),
                models = [];
    
            if (carMaker.length > 0)
                models = $.map(carMaker[0].models, function(model) { return { name: model.name, value: makerName + '.' + model.name} });
    
            populateSelect($('#model').get(0), models);
            $('#model').trigger('change');
        });
    
        // populating 3rd select list
        $('#model').bind('change', function () {
            var nameAndModel = this.value.split('.'),
                features = [];
    
            if (2 == nameAndModel.length) {
                var makerName = nameAndModel[0], 
                    carModel = nameAndModel[1],
                    carMaker = filterByProperty(carMakers, 'name', makerName);
    
                if (carMaker.length > 0) {
                    var model = filterByProperty(carMaker[0].models, 'name', carModel)
    
                    if (model.length > 0)
                        features = $.map(model[0].features, function(feature) { return { name: feature, value: makerName + '.' + carModel + '.' + feature} })
                }
            }
    
            populateSelect($('#feature').get(0), features);
        })
    
        // alerting value on 3rd select list change
        $('#feature').bind('change', function () { 
            if (this.value.length > 0)
                alert(this.value);
        })
    });
    
        2
  •  3
  •   Jay Corbett    16 年前

    感谢@Marko Dunic的回答,我能够构建一个数组(数据)结构,可以引用它来填充3个选择框。我没有使用实现代码,只是因为我没有完全理解它…它的工作原理是发布的。在学习jQuery之后,我将回到这段代码。 我的代码发布在下面(显然,您对jQuery的引用可能不同)

    <html><head>
    <script language="Javascript" src="javascript/jquery-1.2.6.min.js"></script>
    <script type="text/JavaScript">
    var cars = [
    { name: 'Honda', models: [
    { name: 'Accord', features: ['2dr', '4dr'] },
    { name: 'CRV', features: ['2dr', 'Hatchback'] },
    { name: 'Pilot', features: ['base', 'superDuper'] }
       ]},
    { name: 'Toyota', models: [
    { name: 'Prius', features: ['green', 'superGreen'] },
    { name: 'Camry', features: ['sporty', 'square'] },
    { name: 'Corolla', features: ['cheap', 'superFly'] }
       ]
     }
    ];
    $(function() {
    var options = '' ;
    for (var i = 0; i < cars.length; i++) {
        var opt = cars[i].name ;
        if (i == 0){  options += '<option selected value="' + opt + '">' + opt + '</option>'; }
        else {options += '<option value="' + opt + '">' + opt + '</option>'; } 
    }
    $("#maker").html(options);   // populate select box with array
    
    var options = '' ;
    for (var i=0; i < cars[0].models.length; i++) { 
        var opt = cars[0].models[0].name ;
        if (i==0){options += '<option selected value="' + opt + '">' + opt + '</option>';}
        else {options += '<option value="' + opt + '">' + opt + '</option>';} 
    }
    $("#model").html(options);   // populate select box with array
    
    var options = '' ;
    for (var i=0; i < cars[0].models[0].features.length; i++) { 
        var opt = cars[0].models[0].features[i] ;
        if (i==0){options += '<option selected value="' + opt + '">' + opt + '</option>';}
        else {options += '<option value="' + opt + '">' + opt + '</option>';}
    }
    $("#feature").html(options);   // populate select box with array
    
    $("#maker").bind("click",
        function() {
            $("#model").children().remove() ;       // clear select box
            for(var i=0; i<cars.length; i++) {
                if (cars[i].name == this.value) {
                    var options = '' ;
                    for (var j=0; j < cars[i].models.length; j++) { 
                        var opt= cars[i].models[j].name ;
                        if (j==0) {options += '<option selected value="' + opt + '">' + opt + '</option>';}
                        else {options += '<option value="' + opt + '">' + opt + '</option>';} 
                    }
                    break;
                }
            }
            $("#model").html(options);   // populate select box with array
    
            $("#feature").children().remove() ;     // clear select box
            for(var i=0; i<cars.length; i++) {
                for(var j=0; j<cars[i].models.length; j++) {
                    if(cars[i].models[j].name == $("#model").val()) {
                        var options = '' ;
                        for (var k=0; k < cars[i].models[j].features.length; k++) { 
                            var opt = cars[i].models[j].features[k] ;
                            if (k==0){options += '<option selected value="' + opt + '">' + opt + '</option>';}
                            else {options += '<option value="' + opt + '">' + opt + '</option>';}
                        }
                        break;
                    }
                }
            }
            $("#feature").html(options);   // populate select box with array
        });
    
        $("#model").bind("click",
            function() {
                $("#feature").children().remove() ;     // clear select box
                for(var i=0; i<cars.length; i++) {
                    for(var j=0; j<cars[i].models.length; j++) {
                        if(cars[i].models[j].name == this.value) {
                            var options = '' ;
                            for (var k=0; k < cars[i].models[j].features.length; k++) { 
                                var opt = cars[i].models[j].features[k] ;
                                if (k==0){options += '<option selected value="' + opt  + '">' + opt  + '</option>';}
                                else {options += '<option value="' + opt  + '">' + opt  + '</option>';}
                            }
                            break ;
                        }
                    }
                }
                $("#feature").html(options);   // populate select box with array
        });
    });
    </script>
    </head> <body>
    <div id="selection">
    <select id="maker"size="10" style="{width=75px}"></select>
    <select id="model" size="10" style="{width=75px}"></select>
    <select id="feature" size="10"style="{width=75px}"></select>
    </div></body></html>
    
        3
  •  2
  •   DoctorJava    14 年前

    我真的很喜欢@Marko Dunic的解决方案,但它不能满足我将ID附加到选项的需要。一旦我附加了ID,我意识到我可以使JS代码更小、更简单。我的解决方案是为以下情况设计的:数据来自关系数据库,JSON输入数据保留带有主键/外键的关系结构。以下是JSON数据:

    <html lang="en">
      <head>
        <title>Populate a select dropdown list with jQuery - WebDev Ingredients</title>
        <script type="text/javascript" src="js/jquery-1.4.2.js"></script>
        <script type="text/javascript">
            var types = [ 
                { typeID: 1, name: 'Domestic'},
                { typeID: 2, name: 'Import'},
                { typeID: 3, name: 'Boat'}
            ]
            var makes = [ 
                { typeID: 1, makeID: 1, name: 'Chevy'}, 
                { typeID: 1, makeID: 2, name: 'Ford'}, 
                { typeID: 1, makeID: 3, name: 'Delorean'}, 
                { typeID: 2, makeID: 4, name: 'Honda'}, 
                { typeID: 2, makeID: 5, name: 'Toyota'}, 
                { typeID: 2, makeID: 6, name: 'Saab'} 
            ]       
            var model = [ 
                { makeID: 1,  modelID: 1, name: 'Camaro'}, 
                { makeID: 1,  modelID: 2, name: 'Chevelle'}, 
                { makeID: 1,  modelID: 3, name: 'Nova'}, 
                { makeID: 2,  modelID: 4, name: 'Focus'}, 
                { makeID: 2,  modelID: 5, name: 'Galaxie'}, 
                { makeID: 2,  modelID: 6, name: 'Mustang'}, 
                { makeID: 4,  modelID: 7, name: 'Accord'},
                { makeID: 4,  modelID: 8, name: 'Civic'}, 
                { makeID: 4,  modelID: 9, name: 'Odyssey'}, 
                { makeID: 5,  modelID: 10, name: 'Camry'}, 
                { makeID: 5,  modelID: 11, name: 'Corolla'}
            ]
            // 
            // Put this in a stand alone .js file
            //
            // returns array of elements whose 'prop' property is 'value' 
            function filterByProperty(arr, prop, value) { 
                return $.grep(arr, function (item) { return item[prop] == value }); 
            } 
            // populates select list from array of items given as objects: { name: 'text', value: 'value' } 
            function populateSelect(el, items) { 
                el.options.length = 0; 
                if (items.length > 0) 
                    el.options[0] = new Option('please select', ''); 
                $.each(items, function () { 
                    el.options[el.options.length] = new Option(this.name, this.value); 
                }); 
            }  
            // initialization 
            $(document).ready(function () { 
                // populating 1st select list 
                populateSelect($('#sType').get(0), $.map(types, function(type) { return { name: type.name, value: type.typeID} }));      
                 // populating 2nd select list 
                $('#sType').bind('change', function() { 
                    var theModels = filterByProperty(makes, 'typeID', this.value);
                    populateSelect($('#sMake').get(0), $.map(theModels, function(make) { return { name: make.name, value: make.makeID} })); 
                    $('#sMake').trigger('change'); 
                }); 
                 // populating 3nd select list 
                $('#sMake').bind('change', function() { 
                    var theSeries = filterByProperty(model, 'makeID', this.value);  
                    populateSelect($('#sModel').get(0), $.map(theSeries, function(model) { return { name: model.name, value: model.modelID} })); 
                }); 
            });
        </script>
      </head>
      <body>
        Enter values, click submit, and look at the post parameters
        <form method="get" action="index.php">
                <div id="selection"> 
                    <select id="sType" name="type_id" style="{width=75px}"></select> 
                    <select id="sMake"  name="make_id" style="{width=75px}"></select> 
                    <select id="sModel"  name="model_id" style="{width=75px}"></select> 
                </div>
                <input type="submit">
        </form>
      </body>
    </html>  
    

    请注意,我的解决方案改变了功能,使Make Model成为第二和第三个文本框,Type(国产、进口、船等)成为第一级。我将模板JS减少到23行(更少的注释),同时保留了良好的格式。

    JSON数据很容易从SQL查询中呈现,SQL查询缓存在init上的java列表中,因为类型Make模型很少更改。我不使用任何动态AJAX,因为这会使体系结构复杂化,而且我有一个相对较小的可用值列表,所以我只需在页面请求时发送它。

        4
  •  1
  •   Ionuț Staicu    17 年前

    你应该看看 here 我想是为了你想要的 JSON 我会为你做正确的工作。 无论如何,如果我是你,我会这样做: