在 jQuery UI Selectable 中启用 Shift-Multiselect

Posted

技术标签:

【中文标题】在 jQuery UI Selectable 中启用 Shift-Multiselect【英文标题】:Enable Shift-Multiselect in jQuery UI Selectable 【发布时间】:2012-03-11 14:19:57 【问题描述】:

我想通过按住 shift 在 jQuery UI 可选表中启用多选功能。

如果在鼠标点击时按住 shift,我可能应该这样做

获取最上面的选定元素 获取被点击的元素 选择中间的所有元素

但我找不到如何以干净的方式做到这一点......

目前我在可选配置中得到了这个:

start: function(e)
        
            var oTarget = jQuery(e.target);
            if(!oTarget.is('tr')) oTarget = oTarget.parents('tr');
        

所以oTarget 是被点击的元素(e.currentTarget 是整个表格)但是现在呢?我怎样才能找到哪些元素已经被选中,并且可以告诉我点击的元素是在所选元素之上还是之下,并选择介于两者之间的所有元素?

我现在已经这样解决了,添加到可选择元素中:

jQuery(table).mousedown(function(e)
    
        //Enable multiselect with shift key
        if(e.shiftKey)
        
            var oTarget = jQuery(e.target);
            if(!oTarget.is('.ui-selectee')) oTarget = oTarget.parents('.ui-selectee');

            var iNew = jQuery(e.currentTarget).find('.ui-selectee').index(oTarget);
            var iCurrent = jQuery(e.currentTarget).find('.ui-selectee').index(jQuery(e.currentTarget).find('.ui-selected'));

            if (iCurrent < iNew) 
                iHold = iNew;
                iNew = iCurrent;
                iCurrent = iHold;
            

            if(iNew != '-1')
            
                jQuery(e.currentTarget).find('.ui-selected').removeClass('ui-selected');
                for (i=iNew;i<=iCurrent;i++) 
                    jQuery(e.currentTarget).find('.ui-selectee').eq(i).addClass('ui-selected');
                
                e.stopImmediatePropagation();
                e.stopPropagation();
                e.preventDefault();
                return false;
            
        
    ).selectable(...)

【问题讨论】:

【参考方案1】:

我为该功能编写了简单的插件。它不依赖于 jQuery ui Selectable 插件,据我所知,它可以正常工作。

您可以在此处找到插件代码和简单示例:http://jsfiddle.net/bMgpc/170/

下面写简单的描述。

基本用法:

$('ul').multiSelect();

如果按住“Ctrl”或“Command Key”,则可以一一选择/取消选择元素。

ul - 包含要选择的内部元素的父级。

有多种选择:

keepSelection - true|false - 一个非常重要的标志。如果设置为 true(默认),则如果您单击已选择的元素,则不会清除选择(因为它适用于多个道具) multiselect - true|false - 如果为 false,则只能选择一个元素 selected - 'selected' - 将添加到选定元素的类 filter: - ' > *' - 我们要选择什么元素 unselectOn - false|'selector' - 如果已设置,则如果单击设置,则选择器将被删除 start: false|function - 开始回调 stop: false|function - 停止时回调 取消选择:false|function - 单击设置“unselectOn”选项时的回调

是开发版插件,慎用

【讨论】:

谢谢,我没有直接使用它,但我可以从源头获得所需的想法来解决它。 :) @bardiir,这是最好的方法。当我写这段代码的时候,我脑子里有非常具体的东西,所以为了你自己的目的重写它是最好的方法。【参考方案2】:

环顾四周后,我在仍然使用 jQuery UI 的 Selectable 功能时无法找到解决此问题的方法,所以我写了一个。本质上,它利用 Selectable 的选定/未选定回调来管理 DOM 状态,同时仍然按照标准 Selectable API 尊重回调。它支持以下用例:

单击列表中任意位置的元素之一(shift+click、cntl+click 或 click+drag) Shift+单击列表中的另一个元素 两个端点之间的所有元素都被选中

用于表格:

$('table').shiftSelectable(filter: 'tr');

一些笔记。 (1) 目前只支持兄弟元素。 (2) 它将通过配置选项,您将在表示例中看到以及 Selectable 方法。 (3) 我喜欢 underscore.js,所以它被使用了,尽管它不是必需的。如果您不想使用这个很棒的库,请随意更换它的简单检查和扩展。不,我与 underscore.js 没有任何关系。 :)

table fiddle example

list fiddle example

希望这对其他人有帮助!干杯。

【讨论】:

这对我很有用。唯一缺少的是在jquery-ui#selectable 上显示的“拖动选择范围”框。但我确信有一个简单的解决方法。谢谢!【参考方案3】:

你可以在没有这样的插件的情况下做到这一点:

var prev = -1; // here we will store index of previous selection
$('tbody').selectable(
    selecting: function(e, ui)  // on select
        var curr = $(ui.selecting.tagName, e.target).index(ui.selecting); // get selecting item index
        if(e.shiftKey && prev > -1)  // if shift key was pressed and there is previous - select them all
            $(ui.selecting.tagName, e.target).slice(Math.min(prev, curr), 1 + Math.max(prev, curr)).addClass('ui-selected');
            prev = -1; // and reset prev
         else 
            prev = curr; // othervise just save prev
        
    
);

这里是现场演示:http://jsfiddle.net/mac2000/DJFaL/1/embedded/result/

【讨论】:

这是一个非常干净和基本的实现,我喜欢它。扩展它以进行多选(多次使用 shift-click 部分)也很容易通过一些额外的检查来完成。谢谢! 如果您曾经“拖动”表格中的第一个选项,这会表现出一些奇怪的行为。拖动会导致事件在td 而不是tr 上发生,因此索引更改为更高的值。 可选择的事件触发 both tdtr 所以你可以返回 ui.selected.tagName === 'TD' 嗨!我偶然发现了这一点,我发现通过将 prev 设置为 0 并且不重置它(删除 prev = -1; 行)将使其更像“文件系统”,即它允许重复多选,如果取消选择元素您向它们移动选择,并在没有选择任何元素时从头开始选择。我看不出这有什么缺点,所以也许有人会感兴趣 很棒的解决方案和整合@valepu 的建议让它变得更好!

以上是关于在 jQuery UI Selectable 中启用 Shift-Multiselect的主要内容,如果未能解决你的问题,请参考以下文章

jQuery UI:将 Selectable 与 Draggable 结合起来

在 jQuery UI Selectable 中启用 Shift-Multiselect

Jquery-ui 在位置绝对 div 上可选

jQuery UI 可排序和可选

jQuery UI:“基础不是构造函数”

Selectable() Jquery 移动替代