Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

Using javascript and jquery, to populate related select boxes with array structure

Using answers to this question, I have been able to populate a select box based on the selection of another select box. ( I posted my answer here) Pulling the data from an array structure built server-side, stored in a .js file and referenced in the html page.

Now I would like to add a third select box. If I had 3 sets of data (model, make, options) something like this (pseudo code):

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

Ex: If Honda were selected, the next select box would have [Accord Civic] and if Accord were selected the next select box would have [Lx Dx]

How can I

1) create an array structure to hold the data? such that

2) I can use the value from one select box to reference the needed values for the next select box

Thanks

EDIT

I can create the following, but can't figure out the references in a way that would help populate a select box

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I prefer data structure like this:

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

Given the three select lists with id's: 'maker', 'model' and 'features' you can manipulate them with this (I believe this is pretty self explanatory):

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...