问题
I want to enable multiselect capabilities in a jQuery UI Selectable table by holding shift.
I probably should do something like this if shift is held down on mouseclick
- Get topmost selected element
- Get clicked element
- Select all elements in between
but i can't find how to do this in a clean way...
At the moment i got this inside the selectable configuration:
start: function(e)
{
var oTarget = jQuery(e.target);
if(!oTarget.is('tr')) oTarget = oTarget.parents('tr');
}
So oTarget
is the clicked element (and e.currentTarget
is the whole table) but now what? How can i find which elements are already selected in a way that can tell me if the clicked element is over or below the selected ones and select everything in between?
I've solved it now like this, added to the selectable element:
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:
I wrote simple plugin for that functionality. It's not dependent on jQuery ui Selectable plugin and as far as i know works fine with it.
You can find plugin code and simple example here: http://jsfiddle.net/bMgpc/170/
Going to write simple description below.
Basic usage:
$('ul').multiSelect();
If you hold "Ctrl" or "Command Key" then you can select/unselect elements one by one.
ul - parent that holds inner elements to be selected.
There are number of options available:
- keepSelection - true|false - quite an important flag. If set to true (default), then selection won't be cleared if you click on already selected element (as it works in with multiple prop)
- multiselect - true|false -if false you can select only one element
- selected - 'selected' - class that will be added to selected element
- filter: - ' > *' - what elements are we going to select
- unselectOn - false|'selector' - if set then if clicked on set selector selectio would be removed
- start: false|function - callback on start
- stop: false|function - callback on stop
- unselecting: false|function - callback when clicked on set "unselectOn" option
It's a dev version plugin, so use with care
回答2:
You can do it without plugins like this:
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
}
}
});
Here is live demo: http://jsfiddle.net/mac2000/DJFaL/1/embedded/result/
回答3:
After looking around I was unable to find a solution to this problem while still using jQuery UI's Selectable function, so I wrote one up. Essentially it taps into the selected / unselected callbacks of Selectable to manage DOM state while still honoring the callbacks as per the standard Selectable API. It supports the following use case:
- Click one of the elements (shift+click, cntl+click, or click+drag also) anywhere in the list
- Shift+click another element in the list
- All elements between plus the two end points become selected
Usage for a table:
$('table').shiftSelectable({filter: 'tr'});
A few notes. (1) It currently only supports sibling elements. (2) It will pass through configuration options as you will see in the table example as well as the Selectable methods. (3) I heart underscore.js so it is used even though for this it is not essential. Feel free to swap out its simple checks and extends if you don't want to use this awesome library. And no, I have no affiliation with underscore.js. :)
table fiddle example
list fiddle example
Hope this helps someone else! Cheers.
来源:https://stackoverflow.com/questions/9374743/enable-shift-multiselect-in-jquery-ui-selectable