使用“shift”键选择多个项目

问题描述 投票:0回答:3

我使用 select2 v.3.5.1 并需要选择多个项目。我想知道,是否可以使用

shift
键选择多个项目?我不想有
multiple select
,只需按住
shift
键选择几个选项即可。非常感谢代码片段。

javascript jquery select jquery-select2
3个回答
0
投票

如果我理解正确,答案可能的解决方案可以基于:

  • data-maxitem 添加到您的选择中
  • 添加委托事件监听器,以便在选择时检测屎键
  • select2-选择 测试是否必须阻止该事件
  • 最后将结果写入div

$(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>


0
投票

您可以通过按住 ctrl 键来完成。 无论如何,如果您要在其他程序中选择列表中的单个项目,那么这是要按的默认键。


0
投票

我试图在 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>

希望这有助于指出正确的道路。我没有在独立页面中测试此代码,但它在我正在开发的应用程序的上下文中运行良好。它已经在生产中使用了近一年,效果非常好!

© www.soinside.com 2019 - 2024. All rights reserved.