Мне очень понравилось решение @Marko Dunic, но оно не соответствовало моим потребностям в прикреплении идентификаторов к опциям. Как только я прикрепил идентификаторы, я понял, что могу сделать код 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 строк (меньше комментариев), сохранив хорошее форматирование.
Данные JSON очень легко визуализировать из запросов SQL, которые кэшируются в списках java при инициализации, поскольку Type-Make-Model редко изменяется. Я не использую динамический AJAX, потому что это усложняет архитектуру, и у меня есть сравнительно небольшой список доступных значений, поэтому я просто отправляю его по запросу страницы.
«Решения должны быть максимально простыми, но не более простыми» - А. Эйнштейн