【问题标题】:How to create a set of dropdowns where the list reduces as you select?如何创建一组下拉列表,列表会随着您的选择而减少?
【发布时间】:2015-03-24 01:22:55
【问题描述】:

我有一个这样的 HTML 表单:

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

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

我该怎么办?

最终解决方案

我最初选择了 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:我还意识到,对于我的应用程序,我更喜欢禁用已经使用的选项,而不是完全从列表中删除它们。

【问题讨论】:

    标签: javascript jquery html knockout.js


    【解决方案1】:

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

    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

    【讨论】:

    • 不错的解决方案。我从不使用 Knockout,总是使用 Angular。我喜欢看到不同之处和相似之处。
    • 非常感谢您解决了我的问题。这让我走上了正确的道路,我能够让它变得更有活力,而不是只期待 3 个选项。
    • 太好了,很高兴它对你有所帮助。
    【解决方案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,您只需禁用选定的选项。我最终选择了 David Sherret 的 Knockout 解决方案,因为我的 select 选项已经从 Knockout 提供,所以它融合得很好。不过,我真的很喜欢这个。谢谢。
    【解决方案3】:

    还有一种更清洁、更简单的方法:http://jsfiddle.net/ejs1d3zb/5/

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

    【讨论】:

    • @EliasSoares 什么不起作用?这不是建设性的批评。小提琴工作并做OP想要的。是的,当然它并不完美,但它是朝着正确方向的推动。
    • 我知道,我没有时间来微调我的答案。正如我所说,它并不完美,但经过一些修改,OP 应该可以得到他想要的。
    • 对,但不要说我的评论没有建设性......我只是说它不起作用。 :)
    • @EliasSoares 哈哈,这要看你怎么看。杯子是半满还是半空:)...
    • 当然……但是,让一个真正的用户使用它,你会发现杯子都是空的。
    【解决方案4】:

    有一个 OnChange 事件应该有某种已采取和可用的列表,并针对每个组合框检查每个列表

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 2020-07-27
      相关资源
      最近更新 更多