WhatsNew

Martin@MBP edited this page Apr 12, 2017 · 2 revisions

Design goals, new and changed features, compared to Dynatree 1.x.

Motivation

While DynaTree 1.x seems to work well for many users, bug-fixing and implementation of new features became increasingly difficult without breaking compatibility.

A new project name was chosen, so we can re-think and change the API, attribute names, events, default behavior, etc. - without confusing users that see references to 'DynaTree' on forums or stackoverflow.

Still most concepts and implementations are based on DynaTree, so we start off with release 2.0.

New Features

  • More robust on (parallel) asynchronous operations (using deferreds/promises)
  • Better maintainability using an extension-module pattern
    The final design was inspired by jsTree, which features a pretty cool plugin concept:
    credits to Ivan Bozhanov!
  • More flexible initialization (unified source option)
  • More consistent API, using naming conventions and best practice from jQuery UI widgets.
  • Table tree support (example)
  • Inline editsupport (example)
  • The tree now behaves more like a form control, i.e. it is 'tabbable' (example)
  • Filter support (example)
  • HTML markup changed (not using <a> tags anymore)
  • New skins (Windows 7, 8, [OS X] Lion, bootstrap, ...)
Other Improvements
Dropped features
  • Required minimum versions for jQuery have been lifted to jQuery 1.7+ and jQuery UI 1.8.6+

Migration from Dynatree 1.x

Please help to improve this document: send suggestions or edit this Wiki, to clarify things.

  • Most attribute names, event names and method signatures have changed.
// Fancytree 2.x            | DynaTree 1.x
// -------------------------+------------------------------
// Requirements
jQuery 1.7+                   jQuery 1.4+  
jQuery UI 1.8.6+              jQuery UI 1.7+

// Class names
Fancytree                     DynaTree
FancytreeNode                 DynaTreeNode

// Attributes
node.expanded                 node.bExpanded 
node.selected                 node.bSelected
node.children                 node.childList
node.key                      node.data.key
node.title                    node.data.title
node.extraClasses             node.data.addClass
node.lazy                     node.data.isLazy
node.folder                   node.data.isFolder
...
tree.root                     tree.tnToot
...

// Note: it is reccomended to use access methods instead:
node.isFolder()
tree.getRootNode()
...

// Methods
tree = $("#tree").fancytree("getTree");
                              tree = $("#tree").dynatree("getTree");

node.toggleSelected()         node.toggleSelect() 
node.setSelected()            node.select()
node.setActive()              node.activate()
...

// Events
beforeExpand(event, data)     onQueryExpand(flag, node)
select(event, data)           onSelect(flag, node)
...

// Options
source                        initAjax, init
...

// <ul>/<li> initialization
<li class='expanded'>         <li class='expand'>

See the API Reference.

  • Some functionality is now implemented as extension and has to be enabled like this:
  $("#tree").fancytree({
    extensions: ["persistence", "dnd"],
    [...]
  });

See the details.

  • New source option for generalized initialization:
  $("#tree").fancytree({
    // source may be Ajax options, a pointer to a <ul> element, a callback, ...
    source: {
      url: "/getTopLevelNodesAsJson"
    },
    lazyLoad: function(event, data){
      // return a source in 'data.result'
      data.result = {
        url: "/getChildrenAsJson",
        data: {key: data.node.key}
      };
    },
    [...]
  });

See the details.

  • All events have been renamed according to common jQuery widget style. Event arguments have been unified to data.
   activate: function(event, data) {
       var node = data.node;
       alert("activated #" + node.key);
   },
   beforeSelect: function(event, data) {
       logEvent(event, data, "current state=" + data.node.isSelected());
       // return false to prevent default behavior (i.e. selecting or deselecting)
       if( data.node.isFolder() ){
           return false;
       }
   },
   select: function(event, data) {
       logEvent(event, data, "current state=" + data.node.isSelected());
       var s = data.tree.getSelectedNodes().join(", ");
       $("#echoSelected").text(s);
   },

See the details.

  • Most asynchronous methods now return $.promise so handling deferred responses is easy:

    node.setExpanded().done(function(){
        alert("expand animation has finished");
    });
  • The generated markup has changed (structure and class names).
    Check your custom CSS.

More Examples
Fancytree 2.x DynaTree 1.x
node.setActive(true, {noEvents: true})
 node.activateSilently(); 
  $("#tree").fancytree("disable");
  tree.disable();
  tree.reload().done(function(){
    // Root node was reloaded
  }).fail(function(){
    // Reload failed
  });
  tree.reload(function(status){
    // Root node was reloaded
  });
  node.addChildren({
    title: "n.a.", 
    checkbox: false, 
    icon: false, 
    selected: true, 
    nodeStatus: "empty", 
    key: "_empty" 
  });
  rootNode.addChild({
    title: "n.a.", 
    hideCheckbox: true, 
    icon: false, 
    select: true, 
    nodeStatus: "empty", 
    key: "_empty" 
  });
$("#tree").fancytree({
  extensions: ["clones", "edit"],
  autoCollapse: true,
    // Pass an array of nodes (and child nodes)
    source: [
      {title: "Node 1", folder: true, lazy: true, 
        treeMode: "variant", 
        keyType:"root", key: "_famtree_", 
        refKey: "_famtree_", 
        extraClasses: "scioFamilyTree" },
      {title: "Node 2", folder: true, lazy: true, 
        treeMode: "struct", 
        keyType: "root", key: "_structtree_", 
        refKey: "_structtree_", 
        extraClasses: "scioStructureTree" }
  ],
  init: function(event, data){
  },
  beforeActivate: function(event, data) {
  },
  click: function(event, data) {
  },
  activate: function(event, data) {
    var node = data.node,
        isUserEvent = event.originalEvent 
                && event.originalEvent.type === "click";
    if( !node.data.isFolder ){
              node.setExpanded(true);
    }
  },
  deactivate: function(event, data) {
  },
  expand: function(event, data) {
  },
  lazyLoad: function(event, data){
      var node = data.node;
          data.result = $.getJSON("tree/getChildren", {
            mode: node.data.treeMode,
            keyType: node.data.keyType,
            key: node.refKey
          });
  },
  render: function(event, data) {
    var node = data.node;
  },
});
$("#tree").dynatree({
  fx: { height: "toggle", duration: 200 },
  autoCollapse: true,
  noLink: true,
    // Pass an array of nodes (and child nodes)
    children: [
      {title: "Node 1", isFolder: true, isLazy: true, mode: "variants", 
        keyType:"root", key: "_famtree_", addClass: "scioFamilyTree" },
      {title: "Node 2", isFolder: true, isLazy: true, mode: "struct", 
        keyType: "root", key: "_structtree_", addClass: "scioStructureTree" }
    ],
    onQueryActivate: function(dtnode) {
      return broadcastEvent("queryModelDeactivate") !== false;
    },
    onClick: function(dtnode, event) {
    },
    onActivate: function(dtnode) {
    },
    onDeactivate: function(dtnode) {
    },
    onExpand: function(flag, dtnode) {
    },
    onLazyRead: function(dtnode){
      dtnode.appendAjax({
        url: "tree/getChildren",
          data: {mode: dtnode.data.mode,
            keyType: dtnode.data.keyType,
            key: dtnode.data.key
          }
      });
    },
    onRender: function(node, span) {
    },
});
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.