Adding Shift Multiselect to jsTree jQuery Plugin

Before beginning development on our inDrop file management application I knew I wanted to use some kind of file tree structure. I searched high and low for a decent jQuery plugin that could pull it off, only to find many failures. Then I found jsTree which in my opinion is the most stable and complete jQuery tree implementation around.

While working with jsTree I noticed there was no way you could hold the shift key and select multiple items in a row, and since in some of his documentation he says he’ll get around to doing it one day, I decided to implement my own version. I didn’t spend night and day refining this algorithm so I can guarantee there is a better way to do it but here’s what works for me, note that I omit all code involving the implementation of jsTree, you can figure it out it’s not tough, I’m using version 0.9.9a in this example:

1. Let’s set up a couple globals first

[javascript]
var kill = false;
var $tree = $.tree.focused();
[/javascript]

2. Now define two functions in case the target of the shift click is a child node or a parent node in relation to your source node:

[javascript]
function selectKids(el, id)
{
if (el.attr(‘id’) == id)
kill = true;
$tree.select_branch(el, true)
if (kill)
return;
$kids = $tree.children(el);
if ($kids.length > 0)
selectKids($kids, id);
}

function selectAncestors(el)
{
$tree.select_branch(el, true);
$anc = $tree.parent(el);
if ($.is_object($anc) && $anc.attr(‘id’) != $sel.attr(‘id’))
selectAncestors($anc);
}
[/javascript]

3. Now define the main function that you will call after you’ve activated jsTree on your list:

[javascript]
$.bindMulti = function(){
$(‘#filelist li > a’).click(function(e){
$sel = $tree.selected;
var selId = $sel.attr(‘id’);
var selOffset = $sel.offset();
var i = 0;
var total = $(‘li.root > ul’).children().length;
if (!$(this).hasClass(‘clicked’) && e.shiftKey)
{
$newSelPar = $(this).parent();
newSelParId = $newSelPar.attr(‘id’);
newSelParOffset = $newSelPar.offset();
while (selId != newSelParId)
{
i++;
if (i > total)
break;
if (selOffset.top < newSelParOffset.top)
{
if ($.is_object($sel.next()))
$sel = $sel.next();
}
else
{
if ($.is_object($sel.prev()))
$sel = $sel.prev();
}
selId = $sel.attr(‘id’);
$tree.select_branch($sel, true);
$kids = $tree.children($sel);
selectKids($kids, newSelParId);
if (kill)
break;
}
kill = false;
return false;
}
});
}
//#filelist is just the id of a div containing the tree
//$.is_object is from phpJS
//.root is the class I added to the root tree node
[/javascript]

And that’s pretty much it, I’d love to hear of any improvements that could be made. Much thanks to phpJS for a great library and jsTree for the great plugin

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *