Javascript 如何创建一组下拉列表,列表会随着您的选择而减少?

Javascript 如何创建一组下拉列表,列表会随着您的选择而减少?,javascript,jquery,html,knockout.js,Javascript,Jquery,Html,Knockout.js,我有这样一个HTML表单: 所有下拉列表都包含相同的列表:选项1、选项2、选项3,用户需要为每个键选择一个值。这项工作如预期般顺利: 然而,我想提高,因为它。键和选项列表都会变得相对较大(比如20)。需要一对一的映射,不能在两个位置选择值。但是当列表很大时,很容易出错并在两个位置选择相同的值。我们进行了一些客户端验证以检查重复项,但我更希望用户体验能够通过从其他下拉列表中删除所选选项,从而无法再次选择它。像这样: 我该怎么办 最终解决方案 我最初选择了淘汰方案,但经过再三考虑,我更喜欢Ri

我有这样一个HTML表单:

所有下拉列表都包含相同的列表:
选项1、选项2、选项3
,用户需要为每个键选择一个值。这项工作如预期般顺利:

然而,我想提高,因为它。
选项列表
都会变得相对较大(比如20)。需要一对一的映射,不能在两个位置选择值。但是当列表很大时,很容易出错并在两个位置选择相同的值。我们进行了一些客户端验证以检查重复项,但我更希望用户体验能够通过从其他下拉列表中删除所选选项,从而无法再次选择它。像这样:

我该怎么办

最终解决方案

我最初选择了淘汰方案,但经过再三考虑,我更喜欢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:我也意识到对于我的申请,我宁愿禁用已经使用过的选项,而不是将它们完全从列表中删除。

有一个OnChange事件应该有某种类型的Take和available列表,并对每个Comobox进行检查。

有一个OnChange事件应该有某种类型的Take和available列表,并对每个Comobox进行检查comobbox

这里有一个非常简单的方法,可以提高效率,但基本思想如下:

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

这里有一个非常简单的方法,可以提高效率,但基本思想如下:

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

您可以像这样隐藏使用过的选项:

$('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();
  });

});


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

$('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);
  });

});

您可以像这样隐藏使用过的选项:

$('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();
  });

});


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

$('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);
  });

});

甚至有一种更干净、更简单的方法:


甚至还有一种更干净、更简单的方法:



很好的解决方案。我从不使用击倒,总是棱角分明。我喜欢看到不同点和相似点。非常感谢你解决了我的问题。这让我走上了正确的道路,我能够让它更具活力,而不是只期望3个选项。太好了,我很高兴它帮助了你。很好的解决方案。我从不使用击倒,总是棱角分明。我喜欢看到不同点和相似点。非常感谢你解决了我的问题。这让我走上了正确的道路,我能够让它更具活力,而不是只期望3个选项。太好了,我很高兴它帮助了你。@EliasSoares什么不起作用?这不是建设性的批评。小提琴工作,做OP想做的事。是的,当然这并不完美,但这是一个正确的方向。我知道,我没有时间调整我的答案。正如我所说,这不是完美的,但经过一些修改,OP应该得到他想要的。对,但不要说我的评论没有建设性。。。我只是说它不起作用@EliasSoares哈哈,这要看你怎么看了。杯子是半满的还是半空的:)……当然。。。但是,让一个真正的用户使用它,你就会看到杯子都是空的。@EliasSoares什么不起作用?这不是建设性的批评。小提琴工作,做OP想做的事。是的,当然这并不完美,但这是一个正确的方向。我知道,我没有时间调整我的答案。正如我所说,这不是完美的,但经过一些修改,OP应该得到他想要的。对,但不要说我的评论没有建设性。。。我只是说它不起作用@EliasSoares哈哈,这要看你怎么看了。杯子是半满的还是半空的:)……当然。。。但是,如果让一个真正的用户使用它,你会发现杯子里全是空的。这些都是很好的解决方案。我特别喜欢#2,在这里您只需禁用选定的选项。我最终选择了David Sherret提供的淘汰赛解决方案,因为我的
select
选项已经由淘汰赛提供,因此它很好地融合了。不过,我真的很喜欢这个。谢谢。这些都是很好的解决方案。我特别喜欢#2,在这里您只需禁用选定的选项。我最终选择了David Sherret提供的淘汰赛解决方案,因为我的
select
选项已经由淘汰赛提供,因此它很好地融合了。不过,我真的很喜欢这个。谢谢