我使用 select2 v.3.5.1 并需要选择多个项目。我想知道,是否可以使用
shift
键选择多个项目?我不想有 multiple select
,只需按住 shift
键选择几个选项即可。非常感谢代码片段。
如果我理解正确,答案可能的解决方案可以基于:
$(document).on('keyup keydown', ".select2-drop-active", function (e) {
console.log('shift: ' + e.shiftKey);
if (e.shiftKey) {
$("#mySelect1").attr('multiple', 'multiple');
} else {
$("#mySelect1").removeAttr('multiple');
}
})
$("#mySelect1").select2()
.on('select2-selecting', function (e) {
var maxItem = $('#mySelect1').data('maxitem');
var shiftKey = $("#mySelect1").attr('multiple') == 'multiple';
var seletedOpt = $('.select2-drop-active .mySelected').length;
console.log('maxItem: ' + maxItem + ' shiftKey: ' + shiftKey + ' seletedOpt: ' + seletedOpt);
if (shiftKey && seletedOpt < maxItem) {
$('.select2-drop-active .select2-highlighted').addClass('mySelected');
if ($('.select2-drop-active .mySelected').length >= maxItem) {
$("#mySelect1").removeAttr('multiple');
var selectedOption = $('.select2-drop-active .mySelected').map(function (idx, ele) {
return ele.textContent;
}).get().join(' ');
setTimeout(function() {
$('.select2-container a span:first').text(selectedOption);
}, 100, selectedOption);
} else {
e.preventDefault();
}
} else {
$("#mySelect1").removeAttr('multiple');
}
});
.mySelected {
background: #3875d7;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://rawgit.com/cdnjs/cdnjs/master/ajax/libs/select2/3.5.1/select2.min.css" rel="stylesheet"/>
<script src="https://rawgit.com/cdnjs/cdnjs/master/ajax/libs/select2/3.5.1/select2.min.js"></script>
<select id="mySelect1" data-maxitem="2" style="width: 100%;">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
您可以通过按住 ctrl 键来完成。 无论如何,如果您要在其他程序中选择列表中的单个项目,那么这是要按的默认键。
我试图在 2022 年实现这一目标。我进行了广泛的搜索,但没有一个解决方案对我来说非常有效,我怀疑可能是由于最新版本的 select2 的变化。经过多次实验,我想出了一个有效的解决方案,当同一页面上有多个 select2 小部件时它也有效。
该解决方案将设置页面上的每个 select2 小部件以通过按住 Shift 键来选择两个项目之间的每个项目。选择第一个项目后可以松开shift键,以防需要滚动或其他操作,只要在单击第二个项目之前再次按住它即可。无论您选择第一项是列表中较靠下的项目还是列表中较靠上的项目,它都有效。您可以通过释放 Shift 并再次按住它来选择多个单独的项目块,然后单击另一组项目(这样您就可以快速选择项目 1-5、9-15 和 20-25),只需单击 6 次.
它还要求每个 select2 有一个 id,并被赋予类“select2multiplewidget”(或者如果您修改了下面的 javascript 代码,您可以使用其他共享类名)
请注意,我在我的应用程序中使用 Django,因此所使用的特定类名可能来自 Django 的实现,尽管我怀疑情况确实如此。
要添加的Javascript代码(我的解决方案)
var count_shift = 0;
var shift_array = [];
$(document).ready(function() {
//
// Tell your app whether or not the shift key is being held down
$('.select2-search__field').on('keydown', function(e) {
if (e.keyCode === 16) {
isShiftDown = true;
}
}).on('keyup', function(e) {
if (e.keyCode === 16) {
isShiftDown = false;
}
});
// This event is used when the text box doesn't have focus.
$(window).on("keydown", function(e) {
if (e.keyCode === 16) {
isShiftDown = true;
}
}).on("keyup", function(e) {
if (e.keyCode === 16) {
isShiftDown = false;
}
});
//
// Event handlers to select a range of items
$('.select2multiplewidget').each(function() {
$(this).on('select2:closing', function () {
// To be exact, there's no need to return true.
return !isShiftDown;
}).on("select2:select", function (e) {
if (isShiftDown) {
var _id = $(document).find('li.select2-results__option--highlighted').attr('data-select2-id');
var _n = parseInt(_id.split('-')[4]);
shift_array.push({
id: _id,
data: e.params.data,
n: _n
});
count_shift++;
}
//
// This part is allowing you to click either the lowest or highest item first and create the range from either direction.
if (count_shift == 2) {
var lower = (shift_array[0].n < shift_array[1].n ? shift_array[0].n : shift_array[1].n);
var higher = (shift_array[1].n > shift_array[0].n ? shift_array[1].n : shift_array[0].n);
//
// Get current selections
var curVals = $(this).val();
for(var i = lower+1; i < higher; i++)
curVals.push(i.toString());
$(this).val(curVals);
$('#select2-' + this.id + '-results').find('.select2-results__option').each(function() {
var thisn = parseInt($(this).attr('data-select2-id').split('-')[4]);
if((thisn > lower) && (thisn < higher)) {
$(this).attr('aria-selected', 'true');
}
});
$(this).trigger("change");
$(this).select2('close');
count_shift = 0;
shift_array = [];
}
});
});
});
Django 中的 forms.py。 这会生成一系列 select2 多个下拉列表来指定州、DMA 或县的区域分组。这是作为如何定义该字段的示例提供的,并且是在更大的流程的背景下进行的。它是生成项目表单类的表单工厂函数的片段
i = 0
while i < instance.num_regions:
self.fields[f'region_definition_{i}'] = forms.MultipleChoiceField(
label="",
help_text="Select all of the states to include in this region. You can select multiple at once by holding control or shift. Filter the list by typing into the field.",
widget=Select2MultipleWidget(attrs={
'data-maxitem': len(STATE_CHOICES),
'multiple': 'multiple'
}),
choices=STATE_CHOICES,
initial=([] if (len(instance.region_definitions) < i+1) else models.mask_region_choices(STATE_CHOICES, instance.region_definitions[i].split(','))),
required=True,
)
下面我提供了 HTML 源代码和检查元素的代码,以供参考,因此这个答案在 Django 上下文之外很有用:
HTML 源代码由模板渲染生成
<div class="form-group col-xl-5" >
<div id="div_id_region_label_0" class="form-group">
<div class="">
<input type="text" name="region_label_0" value="Northeast" maxlength="50" minlength="2" class="textinput textInput form-control" required id="id_region_label_0">
<small id="hint_id_region_label_0" class="form-text text-muted">Enter the reporting label for this region.</small>
</div>
</div>
</div>
<div class="form-group col-xl-5" >
<div id="div_id_region_definition_0" class="form-group">
<div class="">
<select name="region_definition_0" lang="None" data-minimum-input-length="0" data-theme="default" data-allow-clear="false" data-maxitem="48" multiple class="select2multiplewidget form-control custom-select django-select2" required id="id_region_definition_0">
<option value="1">Alabama</option> <option value="2">Alaska</option>
<option value="3">Arizona</option> <option value="7" selected>Connecticut</option>
<option value="8">Delaware</option> <option value="9">Florida</option>
<option value="10">Georgia</option> <option value="11">Hawaii</option>
<option value="12">Idaho</option> <option value="13">Illinois</option>
<option value="14">Indiana</option> <option value="15">Iowa</option>
<option value="16">Kansas</option> <option value="17">Kentucky</option>
<option value="18">Louisiana</option> <option value="19" selected>Maine</option>
<option value="20">Maryland</option> <option value="21" selected>Massachusetts</option>
<option value="22">Michigan</option> <option value="23">Minnesota</option>
<option value="24">Mississippi</option> <option value="25">Missouri</option>
<option value="26">Montana</option> <option value="27">Nebraska</option>
<option value="28">Nevada</option> <option value="29" selected>New Hampshire</option>
<option value="30" selected>New Jersey</option> <option value="31">New Mexico</option>
<option value="32" selected>New York</option> <option value="33">North Carolina</option>
<option value="34">North Dakota</option> <option value="35">Ohio</option>
<option value="36">Oklahoma</option> <option value="37">Oregon</option>
<option value="38" selected>Pennsylvania</option> <option value="39" selected>Rhode Island</option>
<option value="40">South Carolina</option> <option value="41">South Dakota</option>
<option value="42">Tennessee</option> <option value="43">Texas</option>
<option value="44">Utah</option> <option value="45" selected>Vermont</option>
<option value="46">Virginia</option> <option value="47">Washington</option>
<option value="48">Washington DC</option> <option value="49">West Virginia</option>
<option value="50">Wisconsin</option> <option value="51">Wyoming</option>
</select>
<small id="hint_id_region_definition_0" class="form-text text-muted">
Select all of the states to include in this region.
You can select multiple at once by holding control or shift.
Filter the list by typing into the field.
</small>
</div>
</div>
</div>
</div>
模板渲染生成的 HTML 代码使用 Inspect Element(我使用 forms.py 中的 Select2MultipleWidget 生成了我的代码,如果与您相关,您可以在底部看到我正在使用表单工厂函数。这是一个其中一个字段渲染后的示例)
<div id="div_id_region_definition_0" class="form-group"> <div class="">
<select name="region_definition_0" lang="None" data-minimum-input-length="0" data-theme="default" data-allow-clear="false" data-maxitem="48" multiple="" class="select2multiplewidget form-control custom-select django-select2 select2-hidden-accessible" required="" id="id_region_definition_0" data-select2-id="id_region_definition_0" tabindex="-1" aria-hidden="true">
<option value="1">Alabama</option> <option value="2">Alaska</option>
<option value="3">Arizona</option> <option value="7" selected="" data-select2-id="2">Connecticut</option>
<option value="8">Delaware</option> <option value="9">Florida</option> <option value="10">Georgia</option>
<option value="11">Hawaii</option> <option value="12">Idaho</option> <option value="13">Illinois</option>
<option value="14">Indiana</option> <option value="15">Iowa</option> <option value="16">Kansas</option>
<option value="17">Kentucky</option> <option value="18">Louisiana</option>
<option value="19" selected="" data-select2-id="3">Maine</option> <option value="20">Maryland</option>
<option value="21" selected="" data-select2-id="4">Massachusetts</option> <option value="22">Michigan</option>
<option value="23">Minnesota</option> <option value="24">Mississippi</option>
<option value="25">Missouri</option> <option value="26">Montana</option>
<option value="27">Nebraska</option> <option value="28">Nevada</option>
<option value="29" selected="" data-select2-id="5">New Hampshire</option> <option value="30" selected="" data-select2-id="6">New Jersey</option>
<option value="31">New Mexico</option> <option value="32" selected="" data-select2-id="7">New York</option>
<option value="33">North Carolina</option> <option value="34">North Dakota</option>
<option value="35">Ohio</option> <option value="36">Oklahoma</option>
<option value="37">Oregon</option> <option value="38" selected="" data-select2-id="8">Pennsylvania</option>
<option value="39" selected="" data-select2-id="9">Rhode Island</option> <option value="40">South Carolina</option>
<option value="41">South Dakota</option> <option value="42">Tennessee</option>
<option value="43">Texas</option> <option value="44">Utah</option>
<option value="45" selected="" data-select2-id="10">Vermont</option> <option value="46">Virginia</option>
<option value="47">Washington</option> <option value="48">Washington DC</option> <option value="49">West Virginia</option>
<option value="50">Wisconsin</option> <option value="51">Wyoming</option>
</select>
<span class="select2 select2-container select2-container--default select2-container--focus" dir="ltr" data-select2-id="1" style="width: 562.5px;"><span class="selection">
<span class="select2-selection select2-selection--multiple" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="-1" aria-disabled="false">
<ul class="select2-selection__rendered">
<li class="select2-selection__choice" title="Maine" data-select2-id="472">
<span class="select2-selection__choice__remove" role="presentation">×</span>Maine</li>
<li class="select2-selection__choice" title="Massachusetts" data-select2-id="473">
<span class="select2-selection__choice__remove" role="presentation">×</span>Massachusetts</li>
<li class="select2-selection__choice" title="New Hampshire" data-select2-id="474">
<span class="select2-selection__choice__remove" role="presentation">×</span>New Hampshire</li>
<li class="select2-selection__choice" title="New Jersey" data-select2-id="475">
<span class="select2-selection__choice__remove" role="presentation">×</span>New Jersey</li>
<li class="select2-selection__choice" title="New York" data-select2-id="476">
<span class="select2-selection__choice__remove" role="presentation">×</span>New York</li>
<li class="select2-selection__choice" title="Pennsylvania" data-select2-id="477">
<span class="select2-selection__choice__remove" role="presentation">×</span>Pennsylvania</li>
<li class="select2-selection__choice" title="Rhode Island" data-select2-id="478">
<span class="select2-selection__choice__remove" role="presentation">×</span>Rhode Island</li>
<li class="select2-selection__choice" title="Vermont" data-select2-id="479">
<span class="select2-selection__choice__remove" role="presentation">×</span>Vermont</li>
<li class="select2-search select2-search--inline">
<input class="select2-search__field" type="search" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" placeholder="" style="width: 0.75em;"></li>
</ul>
</span></span>
<span class="dropdown-wrapper" aria-hidden="true"></span></span>
<small id="hint_id_region_definition_0" class="form-text text-muted">Select all of the states to include in this region. You can select multiple at once by holding control or shift. Filter the list by typing into the field.</small>
</div>
</div>
希望这有助于指出正确的道路。我没有在独立页面中测试此代码,但它在我正在开发的应用程序的上下文中运行良好。它已经在生产中使用了近一年,效果非常好!