What's new in TreeV3


New HTML/CSS structure

Nested divs

Previous tree used a list of divs, each of them was indented with grid and spacers to right level. The new tree uses natural nested divs structure (children' divs inside parent's div). Grid is contigous and structure is displayed correctly for any node/font size

All design in CSS through classes and class combinations

All image and size information was removed from JS code. There is a bunch of classes applied to nodes, that may denote node folder state, node type, show if there are children, etc. CSS moves this logical classes into style

Different trees be styled with different CSS class families

Want to put 2 differently styled trees on a page? Give them different classPrefix.

Multiline content support

Rich content support was incomplete, because list-of-divs model could not handle arbitrary-sized nodes. Now you may have <br>, <p> and any other width/height modifiers.

Event system modified

nodeDOMCreated event was removed. That's because listeners are bound to tree and may want to modify the new node, but that's only possible when the node is being bound to the tree, not when it was created and hanging around. afterTreeChange was introduced to help listeners to (un)bind nodes the right moment

All events were renamed to better reflect the moment of their publishing

afterExpand, afterCollapse events now fire when the animation (e.g fading in or out) finishes, not when the actual expand/collapse is called.

Lazy widget creation

Before TreeV3, all nodes must be widgets. A node is added - hence graphical widget is created. For performance reasons that behavior was altered. Now when you add a node, you may actually add a "data object", containing node data, e.g {title:"new node"}. You may want to add a large nested branch of such data objects, like {title:"new", children:[...data objects..]}.

Data objects will become real members of children array (you may recursively search them, modify etc), but graphical widgets will be created only when visitor expands them.

The compatibility drawback of such behavior is that old code may erroneously call *widget* methods on *data objects* while recursively traversing a tree, e.g with Widget#getDescendants. You should change such code to use TreeCommon#processDescendants, or handle data objects in special way.

There are no special mechanisms to add laziliy instantiated "data objects". You may manipulate them simply modifying children array, but no events are thrown until a real widget appears on the scene. In most cases that is fine, but you are free to "disable" lazy widget creation - do not modify children directly and enable tree.eagerWidgetInstantiation

Tree extensions

Many features were moved from core into extensions

  • Added TreeDocIconExtension instead of builtin childIcon support
  • Selector now only throws events, not doing anything with nodes
  • Out-of-the box extensions introduced to be examples and handle well-known requirements

Implicit helpers removed

The Tree is actually a pack of loosely coupled components, connected through events. To keep things simple and also for compatibility reasons, such components(controller,selector...) were created implicitly, if not declared. But actually this proved to be a source of questions and misunderstandings. So now nothing is created implicitly, read how-to and declare things.

RPC has both sync/async modes

Old callbacks code was removed in favor to dojo.Deferred. Now all operations may be async and run your callbacks at the end.

Drag'n'drop changes

Multiple selection and multiple drag'n'drop (not ready yet)

Sounds simple enough.. Select multiple nodes with ctrl and get them with selector.selectedNodes. instead of removed selectorNode call.

Drop of any source, not just tree node

If treeNode property is empty, tree will create a new node from the data returned by source.getTreeNode, then source.onDrop will be called to remove old node.

Inline node editing

It became possible to edit nodes inline, using TreeEditor. Base variant uses RichText widget, you can make another wrapper though. Remote calls can be made on save only, or on start/cancel too e.g for locking purposes.