5级相互依赖的选择列表

时间:2012-04-09 00:44:40

标签: javascript jquery

我很高兴有这样的地方让人们可以解决他们的问题,即使是像我这样的初学者!我不知道从这里走了。

我正在尝试创建一个相互依赖的列表,列出汽车品牌,汽车模型,年份,驱动程序和规模。

我创建了字段,我可以根据所做的选择来填充汽车品牌和汽车模型。根据前面框中的选择,我不知道如何填充'year'字段。我知道第一个盒子需要一个功能。这是我的代码“

HTML:

<form name="selectionForm">
    <select name="makes" id="makes" size="3" style="width:125px">
        <option selected>Select a Make>></option>
    </select>
    <select name="models" id="models" size="3" style="width:125px"></select>
    <select name="years" id="years" size="3" style="width:125px"></select>
    <select name="drivers" id="drivers" size="3" style="width:125px"></select>
    <select name="scales" id="scales" size="3" style="width:125px"></select>
</form>

JavaScript的:

jQuery(function($) {
    initModels();

    function initModels() {
        var makesAndModels = {
            'Ford': ['Fiesta', 'Focus', 'Mondeo'],
            'Vauxhall': ['Astra', 'Cavalier', 'Vectra']
        };

        // Populate makes
        $.each(makesAndModels, function (k, v) {
            $('#makes').append('<option>' + k + '</option>');
        });

        // Populate models
        $('#makes').change(function() {
            var $models = $('#models');

            $models.html("");

            var models = makesAndModels[$(this).val()];

            $.each(models, function (k, v) {
                $models.append('<option>' + v + '</option>');
            });
        });
    }
});

我非常感谢你们的一些指示,因为我不知道从哪里开始。

2 个答案:

答案 0 :(得分:7)

好的,所以这是一个很长的答案,并且花了很长时间准备,所以请耐心等待(并做好准备)。此外,如果您不想阅读本文,则下面有jsFiddle

将每辆车作为单个物品存放会更好。如果您有数据库(或计划将来继续使用),这就是您的数据存储方式。嵌套数组也会产生指数级的痛苦,因此最好不要使用它们。首先,我们将您的数据结构更改为:

var vehicles = [
    { make: 'Ford', model: 'Fiesta', year: '2001', driver: 'me', scale: '1:43' },
    { make: 'Ford', model: 'Fiesta', year: '2005', driver: 'me', scale: '1:33' },
    { make: 'Ford', model: 'Focus', year: '1999', driver: 'you', scale: '1:18' },
    { make: 'Ford', model: 'Modeo', year: '1998', driver: 'Nigel Mansell', scale: '1:43' },
    { make: 'Vauxhall', model: 'Astra', year: '2002', driver: 'James Thompson', scale: '1:43' },
    { make: 'Vauxhall', model: 'Vectra', year: '2000', driver: 'Jason Plato', scale: '1:18' }
];

首先,首先预先推荐初始选择框:

var makes = get_distinct(vehicles, 'make');
$.each(makes, function(index, value) {
   $('select#make').append('<option value="' + value + '">' + value + '</option>')
});

一旦你这样做,你需要设置一种过滤数据的方法。您将需要通过所选选项过滤车辆并获取不同值的功能。下面的filter_vehicles()可怕的,但我很累,而且已经很晚了,所以它必须这样做。你最好让这种动态变得更好,并且会有一个简单的解决方案,但我的大脑现在已经被炒了。

function filter_vehicles() {
    return $.grep(vehicles, function(n, i) {
        if ($('#driver').val() != '')
            return n.make == $('#make').val() && n.model == $('#model').val() && n.year == $('#year').val() && n.driver == $('#driver').val();
        if ($('#year').val() != '')
            return n.make == $('#make').val() && n.model == $('#model').val() && n.year == $('#year').val();
        if ($('#model').val() != '')
            return n.make == $('#make').val() && n.model == $('#model').val();
        else
            return n.make == $('#make').val();
    });
}

// returns distinct properties from an array of objects
function get_distinct(array, property) {
   var arr = [];

   $.each(array, function(index, value) {
       if ( $.inArray(value[property], arr) == -1 ) {
           arr.push(value[property]);
       }
   });

   return arr;
}

然后您需要更新选择框。您可以通过在每个单独的选择框上定位更改事件来手动执行此操作,但您也可以通过将事件附加到所有选择框来动态执行此操作。我更喜欢这种方法,因为在添加其他字段时不会增加任何开销。

$('select').change(function() {
    // don't execute if this is the last select element
    if ($(this).is(':last')) return;

    // clear all of the following select boxes, leaving a blank option
    $(this).nextAll().html('<option></option>');

    // get list of vehicles filtered by all the previous parameters
    var filtered_vehicles = filter_vehicles();

    // get the next select element
    var next = $(this).next();

    // get the distinct values from our list of filtered vehicles
    var values = get_distinct(filtered_vehicles, next.attr('id'));

    // append our options
    $.each(values, function(index, value) {
        next.append('<option value="' + value + '">' + value + '</option>')
    });
});

总而言之,你会得到类似这样的东西:http://jsfiddle.net/8FHZK/

这在SQL中更容易。因此,如果你有一个数据库,你将在服务器上执行查询以返回过滤后的集合,这会删除上面的一些令人讨厌的代码。

我不知道为什么我手动编写了这一切,因为可能有一个jQuery插件已经完成了所有(并且更好)。但是嘿,它已经完成了,我玩得很开心,并且所有的代码都被评论以帮助你学习:)

答案 1 :(得分:0)

$('#years').change(function() {
  //do something like Populate models....
}

那么,有什么区别?