使用 jQuery Select2 隐藏搜索选项
Hide Options On Search with jQuery Select2
我正在使用 Select2 插件,但我这辈子都弄不明白。
基本上我所做的是允许用户从颜色列表和选项 "Other" 中选择 5 种颜色。因此,显示了 10 种左右的颜色,并在底部显示了选择 "Other" 的选项。这些 "Other" 选项在选择时绑定了一个颜色选择器,因此用户可以选择其他颜色。
现在,我允许他们这样做的唯一方法是创建 5 个选项,所有选项的名称都为 "Other",这样用户可以根据需要选择其他 5 次。我的问题是当用户开始在搜索框中键入查询时,我无法正确隐藏不是第一个显示的 "Other" 选项。
我这样做是在打开正常结果的情况下
$('.multi-select').select2('misc options').on("select2:open", function () {
$('.select2-results__option[aria-selected="false"]:contains("Other"):not(:eq(0))').hide();
$('.select2-results__option[aria-selected="false"]:contains("Other"):eq(0)').show();
});
但是,当我像这样将相同的函数绑定到搜索输入元素的变化时
$('.select2-search__field').on('keyup', function () {
$('.select2-results__option[aria-selected="false"]:contains("Other"):not(:eq(0))').css({
'display': 'none',
'opacity': 0
});
$('.select2-results__option[aria-selected="false"]:contains("Other"):eq(0)').css({
'display': 'block',
'opacity': 1
});
});
如果 Select2 决定将结果显示在上面是合适的,我得到了元素的疯狂闪烁,除了顶部 "Other" 选项漂浮在 select 对象上方非常高的地方window space 限制。
闪烁可以归因于插件将显示事件绑定到对象的'keydown'(和'keypress'),所以我绑定到同一个触发器被覆盖,让我绑定到 'keyup',这会导致框显示在按键和释放之间。
我不会修改插件来执行此操作,但是我无法弄清楚我需要在插件内部编辑什么才能使其正常工作。
杂项。我尝试过的事情包括设置 css selector 总是使每个包含 "Other" 的 Select2 对象的第一个框,但是没有 css selector类似“:包含”的东西。
将 class 应用于 Select2 创建的 <li></li>
以指定它是否是 "Other" 选项,但这由插件控制,所以我没有控制权以上。
我明白了。由于字段的值被用作后端字段的 ID,我可以在 ID 上附加“-other-color”,所以我有办法 select 在 CSS 允许超越闪烁。
.select2-results__options li[id*="-other-color"][aria-selected="false"] ~ li[id*="-other-color"][aria-selected="false"]{
display:none!important;
}
由于列表中的子项多于其他颜色选项,您需要根据属性使用波浪号 selector 到 select selector 之后的所有内容正在 selected。
我建议结合使用 select2:select
事件和 maximumSelectionLength
选项,而不是修改 "Other" 结果来实现您正在寻找的结果。
因此,您将从包含默认颜色列表和 一个 "Other" 选项的标记开始。
<select multiple="multiple">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="yellow">Yellow</option>
<option value="custom">Other</option>
</select>
注意,我把"Other"选项的value
设置为custom
,你可以随便选,只要不和颜色冲突就行。这只是将用于确定何时显示颜色选择器的 "flag" 选项。
为了最终将 select 离子的数量限制为仅五种颜色,您可以将 maximumSelectionLength
选项设置为 5
来初始化 Select2。这将告诉 Select2 只允许五个 select 离子,你可以找到一个例子 in the documentation.
var $element = $("select").select2({
maximumSelectionSize: 5
});
现在您已经限制了 select 离子的数量,我们可以继续通过 "Other" 选项实现颜色选择器。我们可以通过侦听 select2:select
选项来检测 "Other" 选项何时被 selected,只要选项被 selected.
就会触发。
$element.on("select2:select", function (evt) {
// handle the "Other" option
});
从那里你需要专门检测 "Other" 选项,所以我们可以检查通过 select2:select
事件传入的数据对象是否有 id
of [=21] =],这是我们之前设置的。由于您希望 selecting 多个自定义颜色选项保持打开状态,我们将在 selected 时立即取消 select "Other" 选项。
function (evt) {
// check for the custom id
if (evt.params.data.id === 'custom') {
// unselect the element, so other custom colors can be picked
evt.params.data.element.selected = false;
// update the selection
$(this).trigger('change');
}
}
从那里开始,您需要实现用户可以选择颜色的部分。为此,我只使用了 prompt
来询问颜色。因为 prompt
是同步的,所以我们可以等待 selection 被给出。但是您的颜色选择器很可能是异步的,因此您可能必须将其余部分放在不同的事件处理程序中。
// prompt the user for a color somehow
var color = prompt("Pick a color, any color");
颜色 select 编辑后,您将需要为其创建自定义 <option selected>
。这是为了将值发送到服务器,这样 Select2 就可以知道 selected.
是什么颜色
// create a new option
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement/Option
var option = new Option(color, color, null, true);
您需要做的就是将它添加到原始 <select>
并触发其上的 change
事件,这样 Select2(和其他组件)就会知道该值已更改。
// add the option to the original select, before the "Other" option
$(option).insertBefore(evt.params.data.element);
// update the selection
$element.trigger('change');
现在 Select2 将显示新的自定义颜色以及已制作的任何其他 select离子。用户还可以通过多次 selecting "Other" 选项来 select 其他颜色。
因此,将它们放在一起可以得到以下代码
var $element = $("select").select2({
maximumSelectionLength: 5
});
$element.on('select2:select', function (evt) {
// check for the custom id
if (evt.params.data.id === 'custom') {
// unselect the element, so other custom colors can be picked
evt.params.data.element.selected = false;
// update the selection
$(this).trigger('change');
// prompt the user for a color somehow
var color = prompt("Pick a color, any color");
// create a new option
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement/Option
var option = new Option(color, color, null, true);
// add the option to the original select, before the "Other" option
$(option).insertBefore(evt.params.data.element);
// update the selection
$element.trigger('change');
}
});
您可以在以下 jsbin 进行实时测试:http://jsbin.com/beluximesi/1/edit?html,js,output
我正在使用 Select2 插件,但我这辈子都弄不明白。
基本上我所做的是允许用户从颜色列表和选项 "Other" 中选择 5 种颜色。因此,显示了 10 种左右的颜色,并在底部显示了选择 "Other" 的选项。这些 "Other" 选项在选择时绑定了一个颜色选择器,因此用户可以选择其他颜色。
现在,我允许他们这样做的唯一方法是创建 5 个选项,所有选项的名称都为 "Other",这样用户可以根据需要选择其他 5 次。我的问题是当用户开始在搜索框中键入查询时,我无法正确隐藏不是第一个显示的 "Other" 选项。
我这样做是在打开正常结果的情况下
$('.multi-select').select2('misc options').on("select2:open", function () {
$('.select2-results__option[aria-selected="false"]:contains("Other"):not(:eq(0))').hide();
$('.select2-results__option[aria-selected="false"]:contains("Other"):eq(0)').show();
});
但是,当我像这样将相同的函数绑定到搜索输入元素的变化时
$('.select2-search__field').on('keyup', function () {
$('.select2-results__option[aria-selected="false"]:contains("Other"):not(:eq(0))').css({
'display': 'none',
'opacity': 0
});
$('.select2-results__option[aria-selected="false"]:contains("Other"):eq(0)').css({
'display': 'block',
'opacity': 1
});
});
如果 Select2 决定将结果显示在上面是合适的,我得到了元素的疯狂闪烁,除了顶部 "Other" 选项漂浮在 select 对象上方非常高的地方window space 限制。
闪烁可以归因于插件将显示事件绑定到对象的'keydown'(和'keypress'),所以我绑定到同一个触发器被覆盖,让我绑定到 'keyup',这会导致框显示在按键和释放之间。
我不会修改插件来执行此操作,但是我无法弄清楚我需要在插件内部编辑什么才能使其正常工作。
杂项。我尝试过的事情包括设置 css selector 总是使每个包含 "Other" 的 Select2 对象的第一个框,但是没有 css selector类似“:包含”的东西。
将 class 应用于 Select2 创建的 <li></li>
以指定它是否是 "Other" 选项,但这由插件控制,所以我没有控制权以上。
我明白了。由于字段的值被用作后端字段的 ID,我可以在 ID 上附加“-other-color”,所以我有办法 select 在 CSS 允许超越闪烁。
.select2-results__options li[id*="-other-color"][aria-selected="false"] ~ li[id*="-other-color"][aria-selected="false"]{
display:none!important;
}
由于列表中的子项多于其他颜色选项,您需要根据属性使用波浪号 selector 到 select selector 之后的所有内容正在 selected。
我建议结合使用 select2:select
事件和 maximumSelectionLength
选项,而不是修改 "Other" 结果来实现您正在寻找的结果。
因此,您将从包含默认颜色列表和 一个 "Other" 选项的标记开始。
<select multiple="multiple">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="yellow">Yellow</option>
<option value="custom">Other</option>
</select>
注意,我把"Other"选项的value
设置为custom
,你可以随便选,只要不和颜色冲突就行。这只是将用于确定何时显示颜色选择器的 "flag" 选项。
为了最终将 select 离子的数量限制为仅五种颜色,您可以将 maximumSelectionLength
选项设置为 5
来初始化 Select2。这将告诉 Select2 只允许五个 select 离子,你可以找到一个例子 in the documentation.
var $element = $("select").select2({
maximumSelectionSize: 5
});
现在您已经限制了 select 离子的数量,我们可以继续通过 "Other" 选项实现颜色选择器。我们可以通过侦听 select2:select
选项来检测 "Other" 选项何时被 selected,只要选项被 selected.
$element.on("select2:select", function (evt) {
// handle the "Other" option
});
从那里你需要专门检测 "Other" 选项,所以我们可以检查通过 select2:select
事件传入的数据对象是否有 id
of [=21] =],这是我们之前设置的。由于您希望 selecting 多个自定义颜色选项保持打开状态,我们将在 selected 时立即取消 select "Other" 选项。
function (evt) {
// check for the custom id
if (evt.params.data.id === 'custom') {
// unselect the element, so other custom colors can be picked
evt.params.data.element.selected = false;
// update the selection
$(this).trigger('change');
}
}
从那里开始,您需要实现用户可以选择颜色的部分。为此,我只使用了 prompt
来询问颜色。因为 prompt
是同步的,所以我们可以等待 selection 被给出。但是您的颜色选择器很可能是异步的,因此您可能必须将其余部分放在不同的事件处理程序中。
// prompt the user for a color somehow
var color = prompt("Pick a color, any color");
颜色 select 编辑后,您将需要为其创建自定义 <option selected>
。这是为了将值发送到服务器,这样 Select2 就可以知道 selected.
// create a new option
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement/Option
var option = new Option(color, color, null, true);
您需要做的就是将它添加到原始 <select>
并触发其上的 change
事件,这样 Select2(和其他组件)就会知道该值已更改。
// add the option to the original select, before the "Other" option
$(option).insertBefore(evt.params.data.element);
// update the selection
$element.trigger('change');
现在 Select2 将显示新的自定义颜色以及已制作的任何其他 select离子。用户还可以通过多次 selecting "Other" 选项来 select 其他颜色。
因此,将它们放在一起可以得到以下代码
var $element = $("select").select2({
maximumSelectionLength: 5
});
$element.on('select2:select', function (evt) {
// check for the custom id
if (evt.params.data.id === 'custom') {
// unselect the element, so other custom colors can be picked
evt.params.data.element.selected = false;
// update the selection
$(this).trigger('change');
// prompt the user for a color somehow
var color = prompt("Pick a color, any color");
// create a new option
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement/Option
var option = new Option(color, color, null, true);
// add the option to the original select, before the "Other" option
$(option).insertBefore(evt.params.data.element);
// update the selection
$element.trigger('change');
}
});
您可以在以下 jsbin 进行实时测试:http://jsbin.com/beluximesi/1/edit?html,js,output