jQuery and jQuery UI Dynamic Tree View Plugin - Fancytree

jQuery and jQuery UI Dynamic Tree View Plugin - Fancytree
File Size: 2.05 MB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT

Fancy Tree is a plugin for jQuery and jQuery UI that allows to create dynamic tree view controls with support for persistence, keyboard, checkboxes, drag and drop, and lazy loading.  jQuery Fancy Tree is the designated successor of DynaTree plugin.

You might also like:

Basic Usage:

1. Include jQuery javascript library and jQuery UI in your document

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>

2. Include jQuery Fancy Tree plugin after jQuery

<script src="jquery.fancytree.js" type="text/javascript"></script>

3. Choose and include a theme css file in your document

<link href="skin-win8/ui.fancytree.css" rel="stylesheet" type="text/css">

4. Create the html

<div id="tree">
<ul id="treeData" style="display: none;">
<li id="id1" title="Look, a tool tip!">item1 with key and tooltip
<li id="id2">item2
<li id="id3" class="folder">Folder with some children
<li id="id3.1">Sub-item 3.1
<li id="id3.1.1">Sub-item 3.1.1
<li id="id3.1.2">Sub-item 3.1.2
<li id="id3.2">Sub-item 3.2
<li id="id3.2.1">Sub-item 3.2.1
<li id="id3.2.2">Sub-item 3.2.2
<li id="id4" class="expanded">Document with some children (expanded on init)
<li id="id4.1"  class="active focused">Sub-item 4.1 (active and focus on init)
<li id="id4.1.1">Sub-item 4.1.1
<li id="id4.1.2">Sub-item 4.1.2
<li id="id4.2">Sub-item 4.2
<li id="id4.2.1">Sub-item 4.2.1
<li id="id4.2.2">Sub-item 4.2.2

4. Call the plugin with default options


5. All the plugin options.

activeVisible: true,
ajax: {
  type: "GET",
  cache: false, // false: Append random '_' argument to the request url to prevent caching.
//          timeout: 0, // >0: Make sure we get an ajax error if server is unreachable
  dataType: "json" // Expect json format and pass json object to callbacks.
},  //
aria: false,
autoActivate: true,
autoCollapse: false,
autoScroll: false,
checkbox: false,
clickFolderMode: 4,
debugLevel: null, // 0..2 (null: use global setting $.ui.fancytree.debugInfo)
disabled: false, // TODO: required anymore?
enableAspx: true, // TODO: document
escapeTitles: false,
extensions: [],
// fx: { height: "toggle", duration: 200 },
// toggleEffect: { effect: "drop", options: {direction: "left"}, duration: 200 },
// toggleEffect: { effect: "slide", options: {direction: "up"}, duration: 200 },
toggleEffect: { effect: "blind", options: {direction: "vertical", scale: "box"}, duration: 200 },
generateIds: false,
icon: true,
idPrefix: "ft_",
focusOnSelect: false,
keyboard: true,
keyPathSeparator: "/",
minExpandLevel: 1,
quicksearch: false,
rtl: false,
scrollOfs: {top: 0, bottom: 0},
scrollParent: null,
selectMode: 2,
strings: {
  loading: "Loading&#8230;",
  loadError: "Load error!",
  moreData: "More&#8230;",
  noData: "No data."
tabindex: "0",
titlesTabbable: false,
tooltip: false,
_classNames: {
  node: "fancytree-node",
  folder: "fancytree-folder",
  combinedExpanderPrefix: "fancytree-exp-",
  combinedIconPrefix: "fancytree-ico-",
  hasChildren: "fancytree-has-children",
  active: "fancytree-active",
  selected: "fancytree-selected",
  expanded: "fancytree-expanded",
  lazy: "fancytree-lazy",
  focused: "fancytree-focused",
  partload: "fancytree-partload",
  partsel: "fancytree-partsel",
  unselectable: "fancytree-unselectable",
  lastsib: "fancytree-lastsib",
  loading: "fancytree-loading",
  error: "fancytree-error",
  statusNodePrefix: "fancytree-statusnode-"
// events
lazyLoad: null,
postProcess: null

Change logs:

v2.21.0 (2017-01-16)

  • [Added] New extension 'ext-dnd5' for native HTML5 drag'n'drop support
  • [Added] rtl option for right-to-left script support
  • [Added] Add $.ui.fancytree.overrideMethod()
  • [Added] hook treeSetOption allows extensions to update on option changes
  • [Changed] standard CSS no longer defines overflow: auto for the container. If the tree container has a fixed height, overflow: auto or overflow: scroll should be added to make it scrollable. (Otherwise this always would be the scroll parent for ext-dnd5.)
  • [Improved] better support for initializing from embedded JSON using the data-type="json" attribute
  • [Fixed] corner case of #658 when ext-edit is loaded, but inactive
  • [Fixed] Don't load 'loading.gif' for glyph skins
  • [Fixed] ext-table: node.render(false) puts first node at end

v2.20.1 (2016-11-20)

  • [Added] rtl option for right-to-left script support
  • [Added] hook treeSetOption allows extensions to update on option changes.

v2.20.0 (2016-11-14)

  • [Added] modifyChild event. This event is also a good place to implement auto sorting
  • [Added] node.triggerModifyChild() and node.triggerModify()
  • [Added] add custom node filter to generateFormElements()
  • [Added] tree.tooltip option allows automatic or custom tooltips
  • [Added] improved tooltip escaping to allow newlines
  • [DEPRECATED] removeNode event. Listen for modifyChild with operation 'remove' instead (which is fired on the parent).
  • [Improved] ThemeRoller theme
  • [Improved] ext-filter
  • add filter option 'hideExpanders' to remove expanders if all child nodes are hidden by filter
  • Filter options and the opts argument of filterNodes() / filterBranches() have been unified.
  • [Fixed] themeroller theme compatible with ext-filter
  • [Fixed] autoCollapse option blocks filter's autoExpand option
  • [Fixed] Filter: Mark matching nodes even if parent was matched in branch mode
  • [Fixed] Exceptions in ext-filter if expression contains special chars
  • [Fixed] ext-filter does not work with ext-edit editCreateNode()
  • [Improved] WAI-ARIA support
  • Set focus to first node on first tab-in
  • Support [home] and [end] keys
  • Set aria-activedescendant on container to active ID
  • Set aria-multiselectable on container if selectMode != 1
  • Set aria-treeitem, -selected, -expanded, on title span instead <li>
  • [Fixed] loadKeyPath() sometimes gets the root wrong
  • [Fixed] Drag & drop helper icons lose indentation with table extension
  • [Fixed] Tabbing is not working if there is an anchor tag in treeview
  • [Fixed] New nodes created with ext-edit, are hidden in filtered trees
  • [Fixed] ext-table: tree.render(true) does not discard existing markup
  • [Fixed] handling of function keys, when quicksearch is on
  • Use QUnit 2.0

v2.19.0 (2016-08-12)

  • [Added] tree.enableUpdate() to temporarily disable rendering to improve performance on bulk updates
  • [Added] modifier class .fancytree-connectors to be set on container
  • Note: Experimental! Not required for skin-xp and not compatible with ext-table
  • [Added] ext-edit: data.originalEvent is now passed to beforeClose
  • [Fixed] Set source option does not update tree
  • [Fixed] node.load(true); doesn't maintain expanded
  • [Fixed] Cannot focus embedded input controls
  • [Improved] Keyboard navigation honors autoScroll option
  • Extensions inherit main version number

v2.18.0 (2016-05-03)

  • [Added] node.discardMarkup() (useful in the collapsed event)
  • [Added] new option .escapeTitles
  • [Added] new callback .enhanceTitle()
  • [Fixed] Html tags included in filter results
  • [Fixed] ext-dnd revert position fails for tables

v2.17.1 (2016-04-12)

  • [Added] node.addClass(), .removeClass(), and .toggleClass()
  • [Added] ext-filter: matcher-callback for tree.filterNodes() may now return "branch" and "skip"
  • [Added] ext-filter: new optionnodata allows to configure a status node for empty results
  • [Added] digits argument to node.getIndexHier(separator, digits).
  • [Added] tree option .tabindex, default is "0". Pass "" to resolve #577.
  • [DEPRECATED] tree option .tabbable. Use .tabindex instead
  • [Added] New option mode='firstChild' for node.moveTo()
  • [Added] New option digits=<int> for node.getIndexHier()
  • [Fixed] ext-filter: branch mode honors autoExpand: true
  • [Fixed] aria-labelledby ids not unique

v2.16.1 (2016-03-19)

  • Fixed missing loading icon in non-bootstrap themes

v2.16.0 (2016-03-16)

  • [Added] ext-clones: new method node.setRefKey(refKey)
  • [Added] modifier class .fancytree-fade-expander to be set on container
  • [Added] ext-dnd: .dragExpand() callback to prevent auto-expand
  • [Improved] load error reporting
  • [Improved] bootstrap theme icons and style (samples use bootstrap 3.3)
  • [Improved] status nodes don't have icons
  • [Improved] pass data argument to source callback
  • [Improved] Handle exceptions inside postProcess
  • [Improved] #568 ext-dnd: Auto-expanding of collapsed nodes should also work when dropping is not allowed
  • [Improved] #567 ext-dnd: fix revert position
  • [Improved] #565 ext-dnd: fix intermediate display of wrong icon (sending 'over' after 'enter')
  • [Fixed] #569 node.navigate does not return a Promise object
  • [Fixed] #563 tree.reactivate(false) sets fancytree-treefocus and tree.reactivate(true) doesn't set keyboard focus
  • [Fixed] #562 Node span tag leaks outside table cell
  • [Fixed] #526 tree.setFocus() does not set keyboard focus
  • Updated to jQuery 1.12.1
  • Updated grunt devDependencies
  • Add jQuery 3.0 beta to test suite
  • Added LICENSE.txt to dist

v2.15.1 (2016-02-24)

  • [Added] [ext-clones] new method node.setRefKey(refKey)
  • [Improved] load error reporting
  • Updated to jQuery 1.12.0
  • Updated grunt devDependencies

v2.14.0 (2016-01-12)

  • [Changed] Renamed class fancytree-statusnode-wait to fancytree-statusnode-loading
  • [Added] new event renderStatusColumns
  • [Deprecated] ext-table option customStatus. Use renderStatusColumns instead
  • [Added] new event clickPaging
  • [Added] new mode nodata for use with node.setStatus()
  • [Added] new method node.addPagingNode()
  • [Added] new method node.replaceWith()
  • node.statusNodeType
  • [Added] new method node.getSelectedNodes()
  • [Added] Helper class glyphicon-spin to allow rotating loading icon with bootstrap
  • [Improved] serialize load requests
  • [Improved] Be more robust if site css defines custom li:before
  • [Improved] ext-table: Define table row templates in <tbody>
  • [Improved] ext-table: <thead> is now optional if <tbody> contains <td>s

v2.14.0 (2015-12-20)

  • [Added] options.icon option/callback.
  • Valid values are true, false, a string containing a class name or image url, or a callback returning that.
  • [Changed] node.icon option. Valid values are true, false, or a string containing a class name or image url.
  • This option existed before, but was stored in the node.data.icon namespace, and did not accept class names.
  • [Deprecated] options.iconClass callback: use options.icon instead
  • [Deprecated] options.icons: use options.icon instead
  • [Deprecated] node.data.iconclass option: use node.icon instead
  • [Deprecated] node.data.icon option: use node.icon instead
  • [Added] tree.clear() method.
  • [Added] ext-persist: new event beforeRestore
  • [Fixed] table-ext: nodeSetExpanded triggers redundant events

v2.13.1-0 (2015-11-16)

  • [Changed] If a node is initalized as lazy: true, and children: [], treat it as 'loaded leaf node'.
  • This is consistent with a lazy node that has no children property at all (i.e. undefined). This would issue a lazyLoad event and a resopnse of [] would mark the node as leaf node.
  • [Added] new function $.ui.fancytree.getTree()
  • [Added] ext-filter methods node.isMatched() and tree.isFilterActive()
  • [Added] CSS for ext-childcounter badges is now part of the standard themes
  • [Added] ext-childcounter method node.updateCounter()`
  • [Fixed] data-hideCheckbox="true"
  • [Fixed] activeVisible option does not work on init
  • [Fixed] ExtPersist requires cookie.js even when not using cookies

v2.12.0-0 (2015-07-26)

  • [Changed] Documented iconClass callback and changed signature from iconClass(node) to iconClass(event, data)
  • [Added] ext-dnd events initHelper and updateHelper
  • [Added] ext-dnd option smartRevert
  • [Added] sample for multi-node drag'n'drop
  • [Added] Sample for modifier keys to control copy/move behavior while dragging
  • [Added] highlight and fuzzy options to ext-filter
  • [Added] fireActivate option to ext-persist (default: true)
  • [Added] new methods tree.findFirst() / .findAll()
  • [Improved] clearFilter() performance
  • [Improved] dnd registers global handlers to cancel on ESC and mousedown
  • [Fixed] Font color while editing node title with bootstrap skin
  • [Fixed] Glyph plugin: Missing margin-left for span.fancytree-custom-icon
  • [Fixed] node.render(true) moves the node to the end of the list
  • [Fixed] focusOnClick option is ignored for tables, if 'dnd' is listed after 'table' extension
  • [Fixed] Double clicking on expander with lazy-load causes assertion error

v2.11.0-0 (2015-07-26)

  • [Changed] Adding fancytree-plain class to container (if not table), allowing for more efficient css
  • [Changed] Use data-uris to inline loading.gif image
  • [Changed] Use padding-left instead of margin-left for table indent
  • [Changed] Add node argument to the toDict() callback
  • [Improved] Nicer bootstrap theme and added table to the example
  • [Improved] ext-dnd supports ext-glyph
  • [Improved] Add counter badges to ext-filter
  • [Fixed] Win8 theme jumpy hover effects
  • [Fixed] ext-edit fails with ext-table, when edit was cancelled
  • [Fixed] ext-table: render(deep) does not work
  • [Fixed] Wide plugin not present in jquery.fancytree-all.min.js

v2.10.2 (2015-07-02)

  • [Fixed] Add dist/skin-custom-1 sample
  • [Fixed] Don't collapse root folder when last node is removed

v2.10.1 (2015-06-28)

  • Revert dist folder layout to v2.9.0, but add dist/skin-common.less

v2.10.0 (2015-06-27)

  • [Changed] New dist folder layout: moved skin-* folders into src/ folder
  • (Note: this change was reverted in v2.10.1)
  • [Improved] Update to jQuery UI 1.11.4, jQuery 1.11.3
  • [Improved] add dist/skin-common.less to fix theme imports
  • [Improved] Support js-cookie (still compatible with jquery-cookie)
  • [Fixed] selected and unselectable shows unchecked checkbox
  • [Fixed] table + themeroller: apply color to TR
  • [Fixed] filterBranches shall use opts to allow autoExpand
  • [Fixed] enter key not handled correctly
  • [Fixed] After deleting last child, parent node remains expanded
  • [Fixed] destroy not removing nodes with ext-table
  • [Fixed] Autoscroll fails with lazyloading returning empty list
  • [Improved] Update to jQuery UI 1.11.4, jQuery 1.11.3

v2.9.0 (2015-04-19)

  • [Changed] ext-filter: tree.filterNodes(filter, opts) now accept an opts object instead of leavesOnly
  • [Improved] only raise exception about data being a string if dataType is "json"
  • [Added] New option autoExpand for [ext-filter]
  • [Fixed] rare exception in dnd events
  • [Fixed] nodeSetActive not returning promise
  • [Fixed] Keyboard focus not working when using dnd extension

v2.8.0 (2015-02-09)

  • [Changed] Deprecated ext-menu (was never officially supported
  • [Improved] Bluring the widget will now blur the focused node too.
  • [Improved] Persistence will only set node focus if widget had focus (otherwise only activate the node).
  • [Improved] Set default focus on first keypress to active node (first node otherwise)
  • [Improved] Accept ECMAScript 6 Promise as source
  • [Added] _superApply() for hook handlers.
  • [Added] eventToString() supports mouse events
  • [Fixed] persistence for focus (when using non-cookie storage)
  • [Fixed] Exception on autoscrolling filtered trees

v2.7.0 (2014-12-22)

  • [CHANGED] Dropped fx option. Use toggleEffect instead.
  • [CHANGED] 'win8' and 'bootstrap' skins where modified to highlight the title span instead of the node span, in order to be compatible with [ext-wide]. The original skins are available as 'skin-win8-n' and 'skin-bootstrap-n' respectively.
  • [Added] ext-wide extension (experimental)
  • [Added] LESS files to distribution
  • [Added] Publish on cdnjs
  • [Improved] tree.reactivate() returns a promise
  • [Fixed] Gaps when filtering in hide mode
  • [Fixed] wrong image on hovers
  • [Fixed] Standard browser behavior prevented (e.g. zoom with Ctrl+'+'/'-')
  • [Fixed] Suppress warning, when dropping top- on top-node

v2.6.1 (2014-12-22)

  • [CHANGED] Dropped fx option. Use toggleEffect instead.
  • [CHANGED] 'win8' and 'bootstrap' skins where modified to highlight the title span instead of the node span, in order to be compatible with [ext-wide]. The original skins are available as 'skin-win8-n' and 'skin-bootstrap-n' respectively.
  • [Added] ext-wide extension (experimental)
  • [Fixed] Gaps when filtering in hide mode (patch by @lefunque)
  • [Fixed] wrong image on hovers
  • [Fixed] Standard browser behavior prevented (e.g. zoom with Ctrl+'+'/'-')
  • [Fixed] Suppress warning, when dropping top- on top-node  

v2.5.1 (2014-11-29)

  • [Added] Option focusOnSelect to set focus when node is checked by a mouse click (default: false)
  • [Added] restore event, sent after ext-persist has restored the tree state
  • [Improved] Better navigation performance when skipping hidden nodes

v2.5.0 (2014-11-24)

  • [CHANGED] [ext-persist] overrideSource option now defaults to true
  • [Added] [ext-filter] Option autoApply re-applies filter on lazy loading (on by default)
  • [Added] quicksearch: navigate to next node by typing the first letters
  • [Improved] [ext-dnd] Make draggable helper and parent configurable
  • [Improved] Add class fancytree-unselectable to respective nodes and dimm unselectable checkboxes
  • [Improved] Update to jQuery 1.1.11, jQuery UI 1.11.2
  • [Improved] New mode 'firstChild' for node.addNode()
  • [Fixed] Fix problem where minExpandLevel was not expanding root node
  • [Fixed] dnd.focusOnClick for jQuery UI 1.11
  • [Fixed] [ext-persist] with selectMode 3

v2.4.2 (2014-11-15)

  • [Improved] Update to jQuery 1.1.11, jQuery UI 1.11.1
  • [Improved] [ext-dnd] Make draggable helper and parent configurable
  • [Improved] Add class fancytree-unselectable to respective nodes and dimm unselectable checkboxes
  • [Fixed] Fix problem where minExpandLevel was not expanding root node
  • [Fixed] dnd.focusOnClick for jQuery UI 1.11

v2.4.1 (2014-09-24)

  • [Fixed] Regression

v2.4.0 (2014-09-20)

  • [CHANGED] Renamed dist/jquery.fancytree-custom.min.js to jquery.fancytree-all.min.js
  • [CHANGED] ext-edit callbacks no longer pass data.value (use data.input.val() instead).
  • [Added] New option id to override default tree id
  • [Added] New argument stopOnParents for tree.generateFormElements()
  • [Added] CDN support (http://www.jsdelivr.com/#!jquery.fancytree)
  • [Added] New method editCreateNode() (ext-edit)
  • [Added] node.isRootNode() and node.isTopLevel()
  • [Improved] node.load() should resolve 'ok', if node is already loaded
  • [Improved] minExpandLevel does not auto-expand
  • [Improved] Allow HTML in tooltips
  • [Fixed] crash in scrollIntoView() when parent is window
  • [Fixed] Checkbox doesn't show with Glyph + Table
  • [Deprecated] node.isRoot(). Use node.isRootNode() instead
  • [Fixed] Fix hasChildren() when children = []
  • [Fixed] ajax LoadError not updated in StatusNode with Table ext

v2.3.1 (2014-08-25)

  • node.load() should resolve 'ok', if node is already loaded
  • minExpandLevel does not auto-expand
  • Fixed: Checkbox doesn't show with Glyph + Table.

v2.3.0 (2014-08-15)

  • [CHANGED] renamed (undocumented) event 'loaderror' to 'loadError'
  • [Added] postProcess now allows to signal error conditions (so it becomes easy to handle custom ajax response formats)
  • [Added] node.setStatus()
  • [Improved] loadError allows to return false to prevent default handling
  • [Fixed] Fix moveTo when moving a node to same parent
  • [Fixed] Glyph expander sometimes disappears

v2.2.1 (2014-06-30)

  • Fix moveTo when moving a node to same parent

v2.0.0-10 (2014-04-13)

  • [Added] New method node.appendSibling()
  • [Improved] setExpanded resolves promise after scrollIntoView
  • [Improved] Allow to return false in lazyLoad for manual loading.
  • [Improved] [ext-table] trigger expand event after animations
  • [Improved] [ext-gridnav] skips empty and merged cells
  • [Improved] grunt build no longer depends on tabfix.py
  • [Fixed] selectMode: 1 + "selected": true looks buggy

v2.0.0-9 (2014-04-03)

  • [Added] New helper method $.ui.fancytree.escapeHtml().
  • [Added] [ext-clones] new method node,reRegister(key, refKey)
  • [Added] Support for bower.
  • [Added] dist/ folder to repository
  • [Improved] [ext-edit] handles <, >, ...
  • [Improved] [ext-table] node.render(force) trigger renderColumns event
  • [Fixed] [ext-table] #178 children are not displayed when filtering

v2.0.0-8 (2014-03-10)

  • [BREAKING CHANGE] node.isStatusNode() is now a function (was a property before). Added new property node.statusNodeType.
  • [BREAKING CHANGE] Renamed ext-awesome to ext-glyph
  • [DEPRECATION] Deprecated event lazyload, use lazyLoad (upper case L) instead.
  • [DEPRECATION] Deprecated methods node.lazyLoad() and node.discard(). use load() and resetLazy() instead.
  • [FEATURE] Added node.isUndefined(), isLoaded(), resetLazy(), load(), resetLazy()
  • [FEATURE] [ext-persist] Added option expandLazy for recursive loading (still experimental).
  • [FEATURE] [ext-filter] 'mode: hide' now works with ext-table (still experimental).
  • [FEATURE] node.makeVisible() accepts options, scrolls into view, and returns a promise.
  • [FEATURE] Sample xxl and bootstrap themes.
  • [CHANGE] nodeRenderStatus() is now implicitly called by nodeRenderTitle().
  • This also means that now all markup and css classes are finshed, when renderNode is fired.
  • [CHANGE] Calling setExpanded() on a leaf node fires .done() (not .fail())
  • [CHANGE] Removing the last child node collapses the parent; lazy nodes become empty (not undefined).

v2.0.0-6 (2014-02-09)

  • Added new `opts` argument to setExpanded()


This awesome jQuery plugin is developed by mar10. For more Advanced Usages, please check the demo page or visit the official website.