【问题标题】:How to prevent multiple selection in jQuery UI Selectable plugin如何在 jQuery UI Selectable 插件中防止多选
【发布时间】:2009-05-14 05:13:37
【问题描述】:

我正在使用 jQuery UI 可选插件。我想一次选择一项。但是 jQuery UI Selectable 插件允许通过单击/拖动/按住 CTRL 键进行多项选择。 有什么办法可以防止多选?

【问题讨论】:

    标签: jquery jquery-ui


    【解决方案1】:

    What i did, is that i allow multiple selection but when the selection is done, i only keep the first element selected

    <ul id="select">
        <li>Row 1</li>
        <li>Row 2</li>
        <li>Row 3</li>
    </ul>
    

    这会选择除第一个元素之外的所有选定元素并删除选定状态。所以最后只会选择一个元素。 event.target 对应我的 ul 元素。

    $('#select').selectable({
        stop:function(event, ui){
            $(event.target).children('.ui-selected').not(':first').removeClass('ui-selected');
        }
    });
    

    我知道这个话题有点老了,但我还是偶然发现了它,所以它可能对其他人有用

    【讨论】:

    • 老不老,你给我指明了正确的方向。谢谢你。
    • 和你一样,我刚刚遇到了这个问题。我在http://stackoverflow.com/a/13727528/1747491 写了一个我觉得更干净的解决方案。此方法使.ui-selecting 样式非常明显。此外,当尝试向下选择列表时,您必须取消选择当前选择的项目(向上不是这样)。
    【解决方案2】:

    这对我有用。它可以防止“套索”多行和 ctrl + 单击。

    $(function() {
    $("#selectable").selectable({
          selecting: function(event, ui){
                if( $(".ui-selected, .ui-selecting").length > 1){
                      $(ui.selecting).removeClass("ui-selecting");
                }
          }
    });
    });
    

    【讨论】:

    • 工作就像一个魅力!最好将$(".ui-selected, .ui-selecting").length 更改为this.element.find(".ui-selected, .ui-selecting").length
    • 我不确定我是否理解转换的建议。这是$(".ui-selected, .ui-selecting").lengthversion that seems to work。这是this.element.find(".ui-selected, .ui-selecting").lengthversion that seems broken,它会引发以下错误:Error: Unable to get value of the property 'find': object is null我对jQuery很陌生,我只是想理解。
    【解决方案3】:

    没有明确的方法。但是,您可以为“Start”或“Selected”事件传入一个回调函数,如果选择了多个元素,则取消选择。

    【讨论】:

    • 您好,如何防止在按住 CTRL 键时选择项目?
    【解决方案4】:

    这可能是一个更好的解决方案:

    $('#selectable').selectable({
        selecting: function (event, ui) {
            $(event.target).children('.ui-selecting').not(':first').removeClass('ui-selecting');
        }
    });
    

    【讨论】:

      【解决方案5】:

      这里有一个比之前发布的更通用的解决方案:

          $element.selectable({
              selecting: function (e, ui) {
                  // force single selection
                  $(e.target).find('.ui-selectee.ui-selecting').not(ui.selecting).removeClass('ui-selecting');
                  $(e.target).find('.ui-selectee.ui-selected').not(ui.selecting).removeClass('ui-selected');
              }
          });
      

      (被选中的对象可能并不总是可选对象的子对象,当您按住 ctrl+单击时,按住“第一个”被选中对象会导致一些奇怪的行为。)

      【讨论】:

        【解决方案6】:

        是的,您可以防止这种行为,只需将公差选项设置为“适合”

        【讨论】:

        • 这解决了部分问题——仍然需要一种方法来防止用户按住 Ctrl 键并通过单击鼠标左键来选择元素
        • 这意味着你必须套索整行而不是行的任何部分
        【解决方案7】:

        您可以在this jQuery forum thread 上找到有关此的有趣讨论。

        【讨论】:

          【解决方案8】:

          您可以像这样创建自定义插件:

          $.widget("xim.singleSelectable", {
              options: {
                  select: null
              },
              _create: function () {
                  var self = this;
                  this.element.addClass('ui-selectable');
                  this.element.delegate('li', 'click', function (e) {
                      self.element.find('>li').removeClass('ui-selected');
                      $(this).addClass('ui-selected');
          
                      if ($.isFunction(self.options.select)) {
                          self.options.select.apply(self.element, [e, this]);
                      }
          
                  });
              },
              selected: function () {
                  return this.element.find('li.ui-selected');
              },
              destroy: function () {
                  $.Widget.prototype.destroy.apply(this, arguments); // default destroy
              }
          });
          

          【讨论】:

            【解决方案9】:

            这里有一些很好的解决方案,但大多数都假设您总是希望在多选情况下选择第一个元素,因为它出现在 DOM 中。

            为了解决这个问题,我保留了一个变量 (lastSelection),其中包含成功请求的最后一个元素(而不是 DOM 中的第一个元素),以便在出现不需要的选择时回退到。

            var lastSelection;// this will record our last successful selection
            
            $('#selectable').selectable({
                filter: '.element',
                selecting: function () {
                    if ($('.ui-selecting').length > 1) {
                        // if selecting multiple (lasso) we will ignore the selection and fallback
                        $('.ui-selecting').removeClass('ui-selecting');
                        $(lastSelection).addClass('ui-selecting');// if no value, nothing will be selected
                    }     
                },
                stop: function () {
                    if ($('.ui-selected').length > 1) {
                        // looks like we have an invalid selection, fallback to lastSelection
                        // this handles the ctrl (windows), cmd (OSX) multi-select cases
                        $('.ui-selected').removeClass('ui-selected');
                        $(lastSelection).addClass('ui-selected');// if no value, nothing will be selected
                    } else {
                        if ($('.ui-selected').first().is('.element')) {
                            // if we successfully found a selection, set it as our new lastSelection value
                            lastSelection = $('.ui-selected')[0];
                        }     
                    }     
                }
            });
            

            注意:如果您想在不使用 ctrl / cmd + click 的情况下取消选择,则必须使用此方法实施解决方法。

            我还想指出,tolerance: 'fit' 只要求套索完全包围目标元素才能选择它,它不会禁用套索选择,除非您的元素不能被包围在可用的套索区域中。 http://api.jqueryui.com/selectable/#option-tolerance

            【讨论】:

              【解决方案10】:

              如果您想禁用非连续多选但仍希望保留拖动选择,您可以这样做。

                       stop: function( event, ui ) {
                              if( $(".ui-selected, .ui-selecting").length > 1){
                                  var elems = $('.ui-selected, .ui-selecting');
              
                                  for(var i = 0; i < elems.length - 1; i++){
                                      if($(elems[i]).closest('td').next('td').text() != $(elems[i+1]).text()){
                                         //Non consecutive selection detected
                                      }
                                  }
                              }
                          }
              

              它本质上检查所有元素是否彼此相邻。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-08-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-02-18
                • 1970-01-01
                • 2011-01-20
                相关资源
                最近更新 更多