我正在使用Select2插件,我不能为我的生活弄清楚这一点。
基本上我正在做的是允许用户从颜色列表和“其他”选项中选择5种颜色。因此显示10种左右的颜色,并在底部选择“其他”。这些“其他”选项在选择时会绑定一个颜色选择器,以便用户可以选择其他颜色。
现在,我允许他们这样做的唯一方法是创建5个选项,所有选项都具有“其他”的名称,以便用户可以选择其他5次。我的问题是当用户开始在搜索框中键入查询时,我无法正确隐藏不是第一个显示的“其他”选项。
我正在这样做,正常结果是这样打开的
$('.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决定由于窗口空间限制而导致结果显示在上方,那么我会疯狂地闪烁元素,除了顶部的“其他”选项之外,它还会高于选择对象。
闪存可以归因于插件绑定对象的'keydown'(和'keypress')上的show事件,因此我对同一触发器的绑定被覆盖,使我绑定到'keyup',使按钮显示在按键和释放按钮之间。
我不是要修改插件来执行此操作,但是我无法弄清楚我需要在插件内编辑什么才能使其工作。
混杂。我尝试过的事情包括设置一个css选择器,使每个Select2对象的第一个框包含“Other”,但是没有css选择器用于像“:contains”这样的东西。
将一个类应用于Select2创建的<li></li>
,指定它是否为“其他”选项,但这是由插件控制的,所以我无法控制它。
答案 0 :(得分:2)
而不是修改&#34;其他&#34;为了实现您的目标,我建议您使用select2:select
事件和maximumSelectionLength
选项的组合。
因此,您将开始使用包含默认颜色列表的标记和一个&#34;其他&#34;选项。
<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>
请注意,我已为&#34;其他&#34;设置value
。 custom
的选项,只要不与颜色发生冲突,您就可以选择任何您想要的内容。这只是&#34;标志&#34;选项,用于确定何时显示颜色选择器。
为了最终将可以选择的数量限制为仅五种颜色,您可以在maximumSelectionLength
选项设置为5
的情况下初始化Select2。这将告诉Select2仅允许五个选择,您可以找到示例in the documentation。
var $element = $("select").select2({
maximumSelectionSize: 5
});
现在您的选择数量有限,我们可以通过&#34;其他&#34;继续实施颜色选择器。选项。我们可以检测到&#34;其他&#34;通过监听select2:select
选项来选择选项,只有在选择了选项时才会触发该选项。
$element.on("select2:select", function (evt) {
// handle the "Other" option
});
从那里你需要专门检测&#34;其他&#34;选项,因此我们可以检查通过select2:select
事件传入的id
custom
的数据对象,这是我们之前设置的。由于您希望保持选择打开多种自定义颜色的选项,我们将立即取消选择&#34;其他&#34;选择它时的选项。
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
是同步的,所以我们可以等待给出选择。但是您的颜色选择器很可能是异步的,因此您可能必须将其余部分放在不同的事件处理程序中。
// prompt the user for a color somehow
var color = prompt("Pick a color, any color");
选择颜色后,您需要为其创建自定义<option selected>
。这样就可以将值发送到服务器,因此Select2可以知道选择了什么颜色。
// 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将显示新的自定义颜色以及已经进行的任何其他选择。用户还可以通过选择&#34;其他&#34;来选择其他颜色。选项多次。
所以,把它们放在一起会给你以下代码
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
答案 1 :(得分:0)
我明白了。由于字段的值被用作后端字段的ID,我可以使用“-other-color”附加ID,因此我有一种方法可以在CSS中选择它,从而超越了闪烁。
.select2-results__options li[id*="-other-color"][aria-selected="false"] ~ li[id*="-other-color"][aria-selected="false"]{
display:none!important;
}
由于列表中的子项多于其他颜色选项,因此您需要使用波形符选择器根据所选属性选择选择器之后的所有内容。