From bfbccf9bf7ee9158426ab39955d643e0c9813da6 Mon Sep 17 00:00:00 2001 From: Abdullah Almsaeed Date: Sun, 19 Feb 2017 10:42:30 -0500 Subject: [PATCH] Create Tree widget --- build/js/Tree.js | 149 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 build/js/Tree.js diff --git a/build/js/Tree.js b/build/js/Tree.js new file mode 100644 index 000000000..7b33e1d3c --- /dev/null +++ b/build/js/Tree.js @@ -0,0 +1,149 @@ +/* Tree() + * ====== + * Converts a nested list into a multilevel + * tree view menu. + * + * @type Function + * @Usage: $('.my-menu').tree(options) + * or add [data-widget="tree"] to the ul element + * Pass any option as data-option="value" + */ ++function ($) { + 'use strict' + + var DataKey = 'lte.tree' + + var Default = { + animationSpeed: 500, + accordion : true, + followLink : false, + trigger : '.treeview a' + } + + var Selector = { + tree : '.tree', + treeview : '.treeview', + treeviewMenu: '.treeview-menu', + open : '.menu-open, .active', + li : 'li', + data : '[data-widget="tree"]', + active : '.active' + } + + var ClassName = { + open: 'menu-open', + tree: 'tree' + } + + var Event = { + collapsed: 'collapsed.tree', + expanded : 'expanded.tree' + } + + // Tree Class Definition + // ===================== + var Tree = function (element, options) { + this.element = element + this.options = options + + $(this.element).addClass(ClassName.tree) + + $(Selector.treeview + Selector.active, this.element).addClass(ClassName.open) + + this._setUpListeners() + } + + Tree.prototype.toggle = function (link, event) { + var treeviewMenu = link.next(Selector.treeviewMenu) + var parentLi = link.parent() + var isOpen = parentLi.hasClass(ClassName.open) + + if (!parentLi.is(Selector.treeview)) { + return + } + + if (!this.options.followLink || link.attr('href') == '#') { + event.preventDefault() + } + + if (isOpen) { + this.collapse(treeviewMenu, parentLi) + } else { + this.expand(treeviewMenu, parentLi) + } + } + + Tree.prototype.expand = function (tree, parent) { + var expandedEvent = $.Event(Event.expanded) + + if (this.options.accordion) { + var openMenuLi = parent.siblings(Selector.open) + var openTree = openMenuLi.children(Selector.treeviewMenu) + this.collapse(openTree, openMenuLi) + } + + parent.addClass(ClassName.open) + tree.slideDown(this.options.animationSpeed, function () { + $(this.element).trigger(expandedEvent) + }) + } + + Tree.prototype.collapse = function (tree, parentLi) { + var collapsedEvent = $.Event(Event.collapsed) + + tree.find(Selector.open).removeClass(ClassName.open) + parentLi.removeClass(ClassName.open) + tree.slideUp(this.options.animationSpeed, function () { + tree.find(Selector.open + ' > ' + Selector.treeview).slideUp() + $(this.element).trigger(collapsedEvent) + }) + } + + // Private + + Tree.prototype._setUpListeners = function () { + var that = this + + $(document) + .off('click', this.options.trigger) + .on('click', this.options.trigger, function (event) { + that.toggle($(this), event) + }) + } + + // Plugin Definition + // ================= + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data(DataKey) + + if (!data) { + var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option) + $this.data(DataKey, new Tree($this, options)) + } + }) + } + + var old = $.fn.tree + + $.fn.tree = Plugin + $.fn.tree.Constructor = Tree + + // No Conflict Mode + // ================ + $.fn.tree.noConflict = function () { + $.fn.tree = old + return this + } + + + // Tree Data API + // ============= + $(window).on('load', function () { + $(Selector.data).each(function () { + Plugin.call($(this)) + }) + }) + +}(jQuery)