Scriptaculous SortableTree

posted: May 30th, 2008 · by: Sven

in: Programming · tagged as: , , ·  23 comments »

For a project I’ve been working on recently I needed a sortable javascript tree widget that allows to drag and drop tree nodes and serialize an ajax call on drop events.

I’ve googled for solutions but did not find anything that implemented the simple things I wanted in a lightweight manner. So I started to check out the Scriptaculous sortable tree option but no matter what I tried I could not get it behave.

A couple of frustrating hours of reading the code and comments on the somewhat sparse Scriptaculous documentation (no offense!) I gave up and decided to implement this myself.

Here’s the result.

I’ve published this on GitHub: scriptaculous-sortabletree and there are two working demos online:

See demo/bold.html and demo/textmate.html for usage. If you’re familiar with Scriptaculous Draggables things should be pretty obvious :)

I haven’t included any fancy stuff (like configuring tree serialization to different query formats) because in Javascript one can always overwrite the default functions that are provided by the library with custom behaviour.

If you think something’s seriously missing though, please drop me a note!

Leave a comment

23 Comments

  1. Kristoff said June 11th, 2008 at 05:56 PM  

    Sir, you just saved me countless hours of pointless tinkering. Thank you very much for sharing this resource and if you ever happen to come through this part of the old continent, I insist on buying you a drink. Thanks again!

  2. Luke said June 19th, 2008 at 03:34 PM  

    Cool, this is exactly what i needed. Thanks.

  3. Sven said June 20th, 2008 at 11:18 AM  

    Nice to see this stuff is useful to you guys. Please let me know if there’s something to improve!

    Kristoff, thanks. I’ve actually never been to Belgium. But if I ever do I’ll get back to you. ;)

  4. Ossi Talonpoika said August 12th, 2008 at 03:32 PM  

    I have spent whole day trying to find this. I was already considering to write whole thing by myself. Thank you!

  5. V said August 18th, 2008 at 01:23 PM  

    Is this working on IE too? From what I’ve seen is throwing an error..

  6. instant.bonsai said August 18th, 2008 at 01:40 PM  

    I had the same problem a few days ago. You have to remove the komma behind the bracket in line 63 to fix this.

  7. V said August 18th, 2008 at 02:05 PM  

    I’m receiving another error now, telling me that “Object doesn’t support this action”.

  8. Pol said October 7th, 2008 at 10:38 AM  

    Hello,

    How to serialize the tree ?

    I would like to have the position of each tree id…

    Is it possible ?

    Thanks !

  9. Zaid said November 15th, 2008 at 11:28 PM  

    Hey - im getting the “Object doesn’t support this action” in IE too (with the rogue comma removed) - has anyone made progress with this at all?

  10. nullify said December 9th, 2008 at 03:27 PM  

    Wonderful stuff! I will definitely implement this in my own page cms which also uses your superb routing-filter plugin. Keep up the good work!

  11. Ryan said December 31st, 2008 at 09:00 PM  

    for everyone getting the “Object doesn’t support this action” error in IE: this actually seems like a problem with the dragdrop.js file that is bundled when you download this. It looks like it is an older version of the script.aculo.us library. All you need to do to fix the problem is go to github and get the most current version of scriptaculous and replace dragdrop.js with the dragdrop.js from the newer version of scriptaculous.

  12. thb said February 10th, 2009 at 12:49 PM  

    awesome, man!

    Thanks a lot!

  13. Chris said March 11th, 2009 at 12:25 AM  

    Should add

    this.tree.unmark_all();

    to the onDrop call so that the script cleans up after itself once the drop is done.

    I was adding padding as the drag was happening depending on hover top bottom or insert and was having the css markers stay causing padding to remain after drop was finished.

    css markers would not clear until another drag was begun.

  14. Rasmus said March 28th, 2009 at 09:56 AM  

    Hi, great stuff. It’ll probably be used in an upcoming version of bromine (bromine.openqa.org)if i can figure out how to put a css class limit on the nodes that are draggable. Any clues?

    var tree = new SortableTree(‘tree’, { draggable: ‘:not(.tc)’ , droppable: { container: ‘:not(.tc)’ },

    the droppable stuff works, but not the draggable. Cheers, Rasmus

  15. Aldrin Cabrera said May 8th, 2009 at 03:37 AM  

    Thanks dude! Thank you so much!

  16. Marc said June 1st, 2009 at 11:20 PM  

    Awesome script, saved me a lot of hours of banging my head against my desk, top notch work

  17. Michal Palma said June 4th, 2009 at 01:45 AM  

    Man this is funny. scriptaculous wrote someone named Tomas Fuchs

  18. Ryan said June 19th, 2009 at 04:52 PM  

    I’ve been using this script for a while – it works great – but there’s one little thing I can’t seem to resolve. The entire containing element (in the example above - the box around the tree) is draggable, rather than just its contents. This gives some weird results when you try to drop it inside of itself.

  19. Guillaume said July 24th, 2009 at 04:27 PM  

    Thanks, This works great. However, I’m trying to add list items thru a button let’s say, (appendChild, etc.), but the newly created item seems not to be draggable at all. Is there any function to call back once the list has been appended ? Or better, is there any function in the class that would let me create new list elements ? I’m pretty new to js and i can look at the code for quite long without finding any solution…

    Thanks

  20. roney said August 8th, 2009 at 08:48 AM  

    Hi,

    I just want to know , How can i stop this sortable package to create sub points upto two levels.

    Thanks Roney

  21. Kieran Simkin said November 21st, 2009 at 01:52 AM  

    Guillaume, I’ve being dynamically adding elements using the following code, assuming $(‘categorytree’) references the

      of your tree and categorymanager_tree is the SortableTree object itself.

      var row = document.createElement('li');
      row.innerHTML='<input type="text" value="'+category_html['name']+'"> <a class="handle" href="#" onclick="return false;">Handle</a>';
      row.setAttribute('id','node_'+id);
      row.setAttribute('data-id',id);
      row.setAttribute('data-order',num);
      row.setStyle("display: none");
      category_manager_tree.setUnsortable();
      $('category_tree').insertBefore(row,$('category_tree').getElementsByTagName("li")[0]);
      new Effect.BlindDown(row,{duration:0.7, afterFinish: function() { 
          category_manager_tree.root.initChildren();
          category_manager_tree.setSortable();
          new Effect.Opacity('ajax-loader',{from: 1.0, to: 0.0, duration: 0.1});
          }});
      

      However, I am now having some troubles with my onDrag handler and I wish to ask if anything about SortableTree makes any assumptions about the ID values of each

    • element eg (node1, node11, node_2 etc)? I notice they all follow a pattern in the examples, but I’m just using database IDs for the numerical ID of each of my
    • elements, could this be causing weird behaviour?

    • Kieran Simkin said November 21st, 2009 at 01:56 AM  

      Guillaume, I’ve being dynamically adding elements using the following code, assuming $(‘categorytree’) references the <ul> of your tree and categorymanager_tree is the SortableTree object itself.

      var row = document.createElement('li');
      row.innerHTML='<input type="text" value="'+category_html['name']+'"> <a class="handle" href="#" onclick="return false;">Handle</a>';
      row.setAttribute('id','node_'+id);
      row.setAttribute('data-id',id);
      row.setAttribute('data-order',num);
      row.setStyle("display: none");
      category_manager_tree.setUnsortable();
      $('category_tree').insertBefore(row,$('category_tree').getElementsByTagName("li")[0]);
      new Effect.BlindDown(row,{duration:0.7, afterFinish: function() { 
          category_manager_tree.root.initChildren();
          category_manager_tree.setSortable();
          new Effect.Opacity('ajax-loader',{from: 1.0, to: 0.0, duration: 0.1});
          }});
      

      However, I am now having some troubles with my onDrag handler and I wish to ask if anything about SortableTree makes any assumptions about the ID values of each <li> element eg (node1, node11, node_2 etc)? I notice they all follow a pattern in the examples, but I’m just using database IDs for the numerical ID of each of my <li> elements, could this be causing weird behaviour?

    • Robert said April 21st, 2010 at 10:31 PM  

      Hi I tried your sortable tree and it looks great in firefox, but there’s a few glitches in IE 8 (at least from my computer)

      1) When dragging, the “orange” drag bar does not complety show. It seems like some padding or something is wrong with drop-top… drop-bottom is fine. What is funny is when I look at it from this website, it’s ok in IE 8. It’s really weird… I even copy pasted the code on this page, same result. Seems the code is different somewhere in here and the downloadable files : example : onroll over, you have orange, not in the demo. I checked the code and i can’t find anything different :/ . Should be easy to fix since it works on this site… (I’m still confused about this one)

      2) I put this tree in a div which I added : scroll: ‘ContainerNotions’, in the draggable options. When I drag n drop, it seems like there a refreshing problem : i need to kinda ‘trigger’ the list again (drag) so the

    • are ok’s (the dragged
    • is positionned correctly in it’s new location but there’s a blank left in the old location).

      Minor: You also need to remove ghosting: true because when dragging, the

    • is not positionned correctly to the mouse cursor (when starting down, dragging upwards)

      3) node 11 cannot be clicked to show/hide contents

      again, all these problemes occur only in ie8 (firefox mac-pc and safari-mac is fine)

      demo link of all these problems : http://simpol.ccdmd.qc.ca/admin/textmate2.html

      Think any fixes might come up ? any help appreciated! Thanks a lot!

Leave a comment

Name required
E-Mail and Website optional

If you can read this, you don't use a typical webbrowser that plays nice with CSS.
Please do not fill in anything here!

Hint: Markdown will be applied to your comment. If you post any code, be sure to escape underscores (like so: \_) if you do not want them to be converted to an <em>phasis.

artweb design
Sven Fuchs
Grünberger Str. 65
10245 Berlin, Germany


http://www.artweb-design.de

Fon +49 (30) 47 98 69 96
Fax +49 (30) 47 98 69 97