如何创建一组下拉菜单,其中列表会在您选择时减少?

时间:2015-03-17 21:10:29

标签: javascript jquery html knockout.js

我有一个像这样的HTML表单:

image 1

所有下拉列表都包含相同的列表:Option 1, Option 2, Option 3,用户需要为每个键选择一个值。这可以正常工作,不用担心:

enter image description here

然而,我想要提升它。 KeysOptions List都可以变得相对较大(例如20)。预计会有一对一的映射,您无法在两个地方选择一个值。但是当列表很大时,很容易出错并在两个地方选择相同的值。我们进行了一些客户端验证以检查重复项,但我更喜欢通过 从其他下拉菜单中删除所选选项以便无法再次选择 的用户体验。像这样:

enter image description here

我该如何解决这个问题?

最终解决方案

我最初选择了Knockout解决方案,但第二个想法,我更喜欢Rick Hitchcock的普通JQuery解决方案,因为我可以轻松地将其插入任何地方而无需任何其他设置。以下是我如何修改Rick的解决方案以使其更具可重用性:

    function reducingDropdowns(dropDownSelector){
        var $dropdowns = $(dropDownSelector);
        $dropdowns.change(function() {
            // First enable all options.
            $dropdowns.find('option').prop('disabled', false);

            // Then for each dropdown, get its current value and
            // disable that option in other dropdowns.
            $dropdowns.each(function() {
                var $currDropdown= $(this);
                var currDropdownValue= $currDropdown.val();
                if(currDropdownValue !== ''){
                    var $otherDropdowns = $dropdowns.not($currDropdown);
                    $otherDropdowns.find('option').each(function() { 
                        var $option = $(this);
                        var optionIsAlreadySelected = $option.val() === currDropdownValue;
                        if(optionIsAlreadySelected)
                            $option.prop('disabled', true);
                    }); 
                }
            });
        });     
    }

现在你可以给你所有相关的下拉菜单一个普通的类,并在任何你需要的地方调用这样的东西:

reducingDropdowns('.myDropdownClass');

谢谢大家的帮助。

PS:我也意识到,对于我的应用程序,我更喜欢禁用已经使用的选项,而不是完全从列表中删除它们。

4 个答案:

答案 0 :(得分:5)

这是一种非常简单的方法,可以提高效率,但这是基本的想法:

<强> HTML

<select data-bind="value: value1, options: options1, optionsCaption: ''"></select>
<select data-bind="value: value2, options: options2, optionsCaption: ''"></select>
<select data-bind="value: value3, options: options3, optionsCaption: ''"></select>

查看模型

var self = this;

this.options = ko.observableArray(['Option 1', 'Option 2', 'Option 3']);

this.value1 = ko.observable();
this.value2 = ko.observable();
this.value3 = ko.observable();

this.options1 = ko.computed(function() {
    return ko.utils.arrayFilter(this.options(), function(f) {
        return f != self.value2() && f != self.value3();
    });
}, this);

this.options2 = ko.computed(function() {
    return ko.utils.arrayFilter(this.options(), function(f) {
        return f != self.value1() && f != self.value3();
    });
}, this);

this.options3 = ko.computed(function() {
    return ko.utils.arrayFilter(this.options(), function(f) {
        return f != self.value1() && f != self.value2();
    });
}, this);

JSFiddle

答案 1 :(得分:2)

您可以隐藏使用的选项,如下所示:

$('select').change(function() {
  $('option').show();

  $('select').each(function() {
    var val= $(this).val();
    $(this).siblings('select')
      .find('option')
      .filter(function() {
        return $(this).val() === val && $(this).val() !== '';
      })
      .hide();
  });

});

<强> Working Fiddle #1


删除项目的另一种方法是禁用它们:

$('select').change(function() {
  $('option').prop('disabled', false);

  $('select').each(function() {
    var val= $(this).val();
    $(this).siblings('select')
      .find('option')
      .filter(function() {
        return $(this).val() === val && $(this).val() !== '';
      })
      .prop('disabled', true);
  });

});

Working Fiddle #2

答案 2 :(得分:1)

甚至可以采用更简洁明了的方式:http://jsfiddle.net/ejs1d3zb/5/

$(function () {

    $('select').change(function (){
    var val = $(this).val();
    $('select option[value='+val+']').not(this.children).remove(); 

    });
});

答案 3 :(得分:-1)

有一个OnChange事件应该有某种可用的列表并检查每个comobbox的每个