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
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(...)
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/
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:
It's a dev version plugin, so use with care
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With