使用 javascript 和 jquery,用数组结构填充相关的选择框
Posted
技术标签:
【中文标题】使用 javascript 和 jquery,用数组结构填充相关的选择框【英文标题】:Using javascript and jquery, to populate related select boxes with array structure 【发布时间】:2010-09-15 21:05:08 【问题描述】:使用this question 的答案,我已经能够根据另一个选择框的选择填充一个选择框。 (I posted my answer here) 从服务器端构建的数组结构中提取数据,存储在 .js 文件中并在 html 页面中引用。
现在我想添加第三个选择框。如果我有 3 组数据(模型、品牌、选项)类似这样(伪代码):
cars : [Honda[Accord[Lx, Dx]], [Civic[2dr, Hatchback]],
[Toyota[Camry[Blk, Red]], [Prius[2dr,4dr]]
例如:如果选择 Honda,下一个选择框将显示 [Accord Civic],如果选择 Accord,则下一个选择框将显示 [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
【问题讨论】:
【参考方案1】:我更喜欢这样的数据结构:
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']
]
];
鉴于三个带有 id 的选择列表:“制造商”、“模型”和“功能”,您可以使用它来操作它们(我相信这是不言自明的):
// 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);
)
);
【讨论】:
感谢您为回答所付出的努力。我尝试了你的代码并且它有效,但我现在没有时间确切地了解它是如何工作的......稍后会回来......但我正在使用数组结构......我想我现在了解如何创建这些数组。再次感谢 数据结构实际上是一个javascript对象。你可以在这里找到一个不错的 JSON 教程:hunlock.com/blogs/… 为此使用 $.grep 和 $.map 只是大师级的操作。很棒的解决方案,我只是将它用作类似东西的基础,并且觉得它是一个更好的程序员。很棒的解决方案。 创建 3 个相关选择框的优秀代码。正是我今天所需要的!【参考方案2】:感谢@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>
【讨论】:
+1 用于填补我的 jQuery+JSON 知识中的空白。谢谢你:)【参考方案3】:我真的很喜欢@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 成为第 2 和第 3 个文本框,而 Type(国内、进口、船等)是第 1 级。我将样板 JS 减少到 23 行(更少 cmets),同时保留了良好的格式。
JSON 数据很容易从 SQL 查询中呈现,因为 Type-Make-Model 很少更改,所以这些查询在初始化时缓存在 java Lists 中。我不使用任何动态 AJAX,因为这会使架构复杂化,而且我的可用值列表相对较少,所以我只是在页面请求时发送它。
“解决方案应该尽可能简单,但不能简单” - A. Einstein
【讨论】:
【参考方案4】:您应该查看here 以了解选择框操作。 对于你想要的,我认为JSON 会为你做正确的工作。 无论如何,如果我是你,我会这样做: 当我更改第一个选择时,我会执行 ajax 请求。使用 ajax 响应,我将填充第二个框。第二个框也一样,第三个框填充了正确的数据。
【讨论】:
以上是关于使用 javascript 和 jquery,用数组结构填充相关的选择框的主要内容,如果未能解决你的问题,请参考以下文章
行业数智化实战系列直播预告 | 个推分享从治数到用数的企业数据智能实践