如何创建一组下拉列表,其中列表随着您 select 而减少?
How to create a set of dropdowns where the list reduces as you select?
我有一个这样的 HTML 表格:
所有下拉列表都包含相同的列表:Option 1, Option 2, Option 3
并且用户需要 select 每个键的值。这按预期工作,不用担心:
但是,我想增强它。 Keys
和 Options List
都可以变得相对较大(比如 20)。预计会有一对一的映射,您不能在两个地方 select 一个值。但是当列表很大时,就很容易出错,select两个地方的值相同。我们做了一些客户端验证来检查重复项,但我更喜欢通过 从其他下拉列表中删除 selected 选项的用户体验,这样它就不会 select再次编辑。像这样:
我该怎么做?
最终解决方案
我最初 select 编辑了 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);
});
}
});
});
}
现在你可以给所有相关的下拉菜单一个通用的 class 并在你需要的任何地方调用这样的东西:
reducingDropdowns('.myDropdownClass');
谢谢大家的帮助。
PS:我还意识到,对于我的应用程序,我更愿意禁用已经使用的选项,而不是将它们从列表中完全删除。
有一个 OnChange 事件应该有某种已获取和可用的列表,并针对每个组合框检查每个列表
这是一种非常简单的方法,可以提高效率,但这是基本思想:
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);
});
});
甚至还有更简洁、更简单的方法:http://jsfiddle.net/ejs1d3zb/5/
$(function () {
$('select').change(function (){
var val = $(this).val();
$('select option[value='+val+']').not(this.children).remove();
});
});
我有一个这样的 HTML 表格:
所有下拉列表都包含相同的列表:Option 1, Option 2, Option 3
并且用户需要 select 每个键的值。这按预期工作,不用担心:
但是,我想增强它。 Keys
和 Options List
都可以变得相对较大(比如 20)。预计会有一对一的映射,您不能在两个地方 select 一个值。但是当列表很大时,就很容易出错,select两个地方的值相同。我们做了一些客户端验证来检查重复项,但我更喜欢通过 从其他下拉列表中删除 selected 选项的用户体验,这样它就不会 select再次编辑。像这样:
我该怎么做?
最终解决方案
我最初 select 编辑了 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);
});
}
});
});
}
现在你可以给所有相关的下拉菜单一个通用的 class 并在你需要的任何地方调用这样的东西:
reducingDropdowns('.myDropdownClass');
谢谢大家的帮助。
PS:我还意识到,对于我的应用程序,我更愿意禁用已经使用的选项,而不是将它们从列表中完全删除。
有一个 OnChange 事件应该有某种已获取和可用的列表,并针对每个组合框检查每个列表
这是一种非常简单的方法,可以提高效率,但这是基本思想:
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);
});
});
甚至还有更简洁、更简单的方法:http://jsfiddle.net/ejs1d3zb/5/
$(function () {
$('select').change(function (){
var val = $(this).val();
$('select option[value='+val+']').not(this.children).remove();
});
});