/* Tree() * ====== * Converts a nested list into a multilevel * tree view menu. * * @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); parent.height('auto'); }.bind(this)); }; 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); // Collapse child items parentLi.find(Selector.treeview).removeClass(ClassName.open).find(Selector.treeviewMenu).hide(); }.bind(this)); }; // Private Tree.prototype._setUpListeners = function () { var that = this; $(this.element).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);