From f1da65609cb3032fa80774d35929627e66e54d8b Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 20 Jun 2015 19:37:01 +0100 Subject: [PATCH 01/52] Work on render changes, work in progress #76 - Split render method, with renderNode added to render an individual node - Resolved test issues with expand collapse functions --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 318 ++++++++++++++++++-------------- src/js/bootstrap-treeview.js | 318 ++++++++++++++++++-------------- tests/lib/bootstrap-treeview.js | 318 ++++++++++++++++++-------------- 4 files changed, 547 insertions(+), 409 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 9e2803815..fe404da84 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this.render()):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):(d.selectable?this.toggleSelectedState(d,f.options):this.toggleExpandedState(d,f.options),this.render())}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this.setExpandedState(b,!1,d)},this))))},g.prototype.toggleSelectedState=function(a,b){a&&this.setSelectedState(a,!a.state.selected,b)},g.prototype.setSelectedState=function(b,c,d){c!==b.state.selected&&(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this.setSelectedState(b,!1,d)},this)),b.state.selected=!0,d.silent||this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,d.silent||this.$element.trigger("nodeUnselected",a.extend(!0,{},b))))},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this.setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){this.initialized||(this.$element.addClass(e),this.$wrapper=a(this.template.list),this.injectStyle(),this.initialized=!0),this.$element.empty().append(this.$wrapper.empty()),this.buildTree(this.tree,0)},g.prototype.buildTree=function(b,c){if(b){c+=1;var d=this;a.each(b,function(b,e){for(var f=a(d.template.item).addClass("node-"+d.elementId).addClass(e.state.checked?"node-checked":"").addClass(e.state.disabled?"node-disabled":"").addClass(e.state.selected?"node-selected":"").addClass(e.searchResult?"search-result":"").attr("data-nodeid",e.nodeId).attr("style",d.buildStyleOverride(e)),g=0;c-1>g;g++)f.append(d.template.indent);var h=[];if(e.nodes?(h.push("expand-icon"),h.push(e.state.expanded?d.options.collapseIcon:d.options.expandIcon)):h.push(d.options.emptyIcon),f.append(a(d.template.icon).addClass(h.join(" "))),d.options.showIcon){var h=["node-icon"];h.push(e.icon||d.options.nodeIcon),e.state.selected&&(h.pop(),h.push(e.selectedIcon||d.options.selectedIcon||e.icon||d.options.nodeIcon)),f.append(a(d.template.icon).addClass(h.join(" ")))}if(d.options.showCheckbox){var h=["check-icon"];h.push(e.state.checked?d.options.checkedIcon:d.options.uncheckedIcon),f.append(a(d.template.icon).addClass(h.join(" ")))}return f.append(d.options.enableLinks?a(d.template.link).attr("href",e.href).append(e.text):e.text),d.options.showTags&&e.tags&&a.each(e.tags,function(b,c){f.append(a(d.template.badge).append(c))}),d.$wrapper.append(f),e.nodes&&e.state.expanded&&!e.state.disabled?d.buildTree(e.nodes,c):void 0})}},g.prototype.buildStyleOverride=function(a){if(a.state.disabled)return"";var b=a.color,c=a.backColor;return this.options.highlightSelected&&a.state.selected&&(this.options.selectedColor&&(b=this.options.selectedColor),this.options.selectedBackColor&&(c=this.options.selectedBackColor)),this.options.highlightSearchResults&&a.searchResult&&!a.state.disabled&&(this.options.searchResultColor&&(b=this.options.searchResultColor),this.options.searchResultBackColor&&(c=this.options.searchResultBackColor)),"color:"+b+";background-color:"+c+";"},g.prototype.injectStyle=function(){this.options.injectStyle&&!c.getElementById(this.styleId)&&a('").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";return this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.css+a},g.prototype.template={list:'',item:'
  • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!0,b)},this)),this.render()},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleSelectedState(a,b)},this)),this.render()},g.prototype.collapseAll=function(b){var c=this.findNodes("true","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.expandAll=function(b){if(b=a.extend({},f.options,b),b&&b.levels)this.expandLevels(this.tree,b.levels,b);else{var c=this.findNodes("false","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!0,b)},this))}this.render()},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&b&&b.levels&&this.expandLevels(a.nodes,b.levels-1,b)},this)),this.render()},g.prototype.expandLevels=function(b,c,d){d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this.expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c=this.getParent(a);c;)this.setExpandedState(c,!0,b),c=this.getParent(c)},this)),this.render()},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b)},this)),this.render()},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):d.selectable?(this.toggleSelectedState(d,f.options),this.render()):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype.toggleSelectedState=function(a,b){a&&this.setSelectedState(a,!a.state.selected,b)},g.prototype.setSelectedState=function(b,c,d){c!==b.state.selected&&(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this.setSelectedState(b,!1,d)},this)),b.state.selected=!0,d.silent||this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,d.silent||this.$element.trigger("nodeUnselected",a.extend(!0,{},b))))},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this.setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).addClass(b.state.checked?"node-checked":"").addClass(b.state.disabled?"node-disabled":"").addClass(b.state.selected?"node-selected":"").addClass(b.searchResult?"search-result":"").attr("data-nodeid",b.nodeId).attr("style",this.buildStyleOverride(b));for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";return this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.css+a},g.prototype.template={tree:'
      ',node:'
    • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!0,b)},this)),this.render()},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleSelectedState(a,b)},this)),this.render()},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 7a82a2eeb..cfde7aaac 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -150,6 +150,7 @@ this.tree = []; this.nodes = []; + this.initialized = false; if (options.data) { if (typeof options.data === 'string') { @@ -321,27 +322,34 @@ var target = $(event.target); var node = this.findNode(target); if (!node || node.state.disabled) return; - + var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { this.toggleExpandedState(node, _default.options); - this.render(); + // this.render(); + // this._expandNode(node); + this._renderNode(node); } else if ((classList.indexOf('check-icon') !== -1)) { this.toggleCheckedState(node, _default.options); this.render(); + // TODO this._checkNode(); } else { if (node.selectable) { this.toggleSelectedState(node, _default.options); + this.render(); + // TODO this._selectNode(node); } else { this.toggleExpandedState(node, _default.options); + // this._expandNode(node); + this._renderNode(node); } - this.render(); + // this.render(); } }; @@ -386,6 +394,7 @@ // Collapse child nodes if (node.nodes && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { + console.log('recurse children') this.setExpandedState(node, false, options); }, this)); } @@ -484,136 +493,186 @@ Tree.prototype.render = function () { + console.log('RENDER'); + if (!this.initialized) { // Setup first time only components - this.$element.addClass(pluginName); - this.$wrapper = $(this.template.list); + this.$wrapper = $(this.template.tree); + this.$element.empty() + .addClass(pluginName) + .append(this.$wrapper); this.injectStyle(); this.initialized = true; } - this.$element.empty().append(this.$wrapper.empty()); + if (!this.tree) return; - // Build tree - this.buildTree(this.tree, 0); + $.each(this.tree, $.proxy(function addRootNodes(id, node) { + node.level = 1; + this._renderNode(node); + }, this)); }; - // Starting from the root node, and recursing down the - // structure we build the tree one node at a time - Tree.prototype.buildTree = function (nodes, level) { + // Creates a new node element from template and + // ensures the template is inserted at the correct position + Tree.prototype._newNodeEl = function (pEl) { - if (!nodes) return; - level += 1; + var $el = $(this.template.node); + + if (pEl) { + console.log('insert'); + this.$wrapper.children().eq(pEl.index()).after($el); + } + else { + console.log('append'); + this.$wrapper.append($el); + } - var _this = this; - $.each(nodes, function addNodes(id, node) { - - var treeItem = $(_this.template.item) - .addClass('node-' + _this.elementId) - .addClass(node.state.checked ? 'node-checked' : '') - .addClass(node.state.disabled ? 'node-disabled': '') - .addClass(node.state.selected ? 'node-selected' : '') - .addClass(node.searchResult ? 'search-result' : '') - .attr('data-nodeid', node.nodeId) - .attr('style', _this.buildStyleOverride(node)); - - // Add indent/spacer to mimic tree structure - for (var i = 0; i < (level - 1); i++) { - treeItem.append(_this.template.indent); - } + return $el; + }; - // Add expand, collapse or empty spacer icons - var classList = []; - if (node.nodes) { - classList.push('expand-icon'); - if (node.state.expanded) { - classList.push(_this.options.collapseIcon); - } - else { - classList.push(_this.options.expandIcon); - } - } - else { - classList.push(_this.options.emptyIcon); + Tree.prototype._collapseNode = function (node) { + if (!node.nodes) return; + console.log('collapseNode - ' + node.text); + $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { + this._collapseNode(node); + if (node.$el) { + node.$el.remove(); + node.$el = null; } + }, this)); + }; - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + Tree.prototype._expandNode = function (node) { + if (!node.nodes) return; + console.log('expandNode - ' + node.text); + var $pEl = node.$el; + $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, $pEl); + $pEl = childNode.$el; + }, this)); + } + + Tree.prototype._renderNode = function (node, pEl) { + console.log('renderNode - ' + node.text); + if (!node) return; + // console.log(node); + if (!node.$el) { + node.$el = this._newNodeEl(pEl); + } + else { + // TODO Don't blanket empty, eval each action + node.$el.empty(); + } - // Add node icon - if (_this.options.showIcon) { - - var classList = ['node-icon']; + node.$el + .addClass('node-' + this.elementId) + .addClass(node.state.checked ? 'node-checked' : '') + .addClass(node.state.disabled ? 'node-disabled': '') + .addClass(node.state.selected ? 'node-selected' : '') + .addClass(node.searchResult ? 'search-result' : '') + .attr('data-nodeid', node.nodeId) + .attr('style', this.buildStyleOverride(node)); - classList.push(node.icon || _this.options.nodeIcon); - if (node.state.selected) { - classList.pop(); - classList.push(node.selectedIcon || _this.options.selectedIcon || - node.icon || _this.options.nodeIcon); - } - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + // Add indent/spacer to mimic tree structure + for (var i = 0; i < (node.level - 1); i++) { + node.$el.append(this.template.indent); + } + + // Add expand, collapse or empty spacer icons + var classList = []; + if (node.nodes) { + classList.push('expand-icon'); + if (node.state.expanded) { + classList.push(this.options.collapseIcon); + } + else { + classList.push(this.options.expandIcon); } + } + else { + classList.push(this.options.emptyIcon); + } - // Add check / unchecked icon - if (_this.options.showCheckbox) { + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); - var classList = ['check-icon']; - if (node.state.checked) { - classList.push(_this.options.checkedIcon); - } - else { - classList.push(_this.options.uncheckedIcon); - } - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + // Add node icon + if (this.options.showIcon) { + + var classList = ['node-icon']; + + classList.push(node.icon || this.options.nodeIcon); + if (node.state.selected) { + classList.pop(); + classList.push(node.selectedIcon || this.options.selectedIcon || + node.icon || this.options.nodeIcon); } - // Add text - if (_this.options.enableLinks) { - // Add hyperlink - treeItem - .append($(_this.template.link) - .attr('href', node.href) - .append(node.text) - ); + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add check / unchecked icon + if (this.options.showCheckbox) { + + var classList = ['check-icon']; + if (node.state.checked) { + classList.push(this.options.checkedIcon); } else { - // otherwise just text - treeItem - .append(node.text); + classList.push(this.options.uncheckedIcon); } - // Add tags as badges - if (_this.options.showTags && node.tags) { - $.each(node.tags, function addTag(id, tag) { - treeItem - .append($(_this.template.badge) - .append(tag) - ); - }); - } + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add text + if (this.options.enableLinks) { + // Add hyperlink + node.$el + .append($(this.template.link) + .attr('href', node.href) + .append(node.text) + ); + } + else { + // otherwise just text + node.$el + .append(node.text); + } - // Add item to the tree - _this.$wrapper.append(treeItem); + // Add tags as badges + if (this.options.showTags && node.tags) { + $.each(node.tags, $.proxy(function addTag(id, tag) { + node.$el + .append($(this.template.badge) + .append(tag) + ); + }, this)); + } - // Recursively add child ndoes - if (node.nodes && node.state.expanded && !node.state.disabled) { - return _this.buildTree(node.nodes, level); - } - }); + // Recursively add child ndoes + if (node.nodes && node.state.expanded && !node.state.disabled) { + this._expandNode(node); + } + else { + this._collapseNode(node); + } }; // Define any node level style override for @@ -687,8 +746,8 @@ }; Tree.prototype.template = { - list: '
        ', - item: '
      • ', + tree: '
          ', + node: '
        • ', indent: '', icon: '', link: '', @@ -841,12 +900,9 @@ @param {optional Object} options */ Tree.prototype.collapseAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.expanded'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, false, options); - }, this)); - - this.render(); + options = $.extend({}, _default.options, options); + options.levels = options.levels || 999; + this.collapseNode(this.tree, options); }; /** @@ -855,11 +911,11 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { + options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, false, options); + this._renderNode(node); }, this)); - - this.render(); }; /** @@ -868,18 +924,8 @@ */ Tree.prototype.expandAll = function (options) { options = $.extend({}, _default.options, options); - - if (options && options.levels) { - this.expandLevels(this.tree, options.levels, options); - } - else { - var identifiers = this.findNodes('false', 'g', 'state.expanded'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, true, options); - }, this)); - } - - this.render(); + options.levels = options.levels || 999; + this.expandNode(this.tree, options); }; /** @@ -888,23 +934,22 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { + options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, true, options); - if (node.nodes && (options && options.levels)) { - this.expandLevels(node.nodes, options.levels-1, options); + if (node.nodes) { + this._expandLevels(node.nodes, options.levels-1, options); } + this._renderNode(node); }, this)); - - this.render(); }; - Tree.prototype.expandLevels = function (nodes, level, options) { - options = $.extend({}, _default.options, options); - + Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { + console.log('test - ' + node.text); this.setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { - this.expandLevels(node.nodes, level-1, options); + this._expandLevels(node.nodes, level-1, options); } }, this)); }; @@ -916,14 +961,14 @@ */ Tree.prototype.revealNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - var parentNode = this.getParent(node); - while (parentNode) { + var parentNode = node; + var tmpNode; + while (tmpNode = this.getParent(parentNode)) { + parentNode = tmpNode; this.setExpandedState(parentNode, true, options); - parentNode = this.getParent(parentNode); }; + this._renderNode(parentNode); }, this)); - - this.render(); }; /** @@ -934,9 +979,10 @@ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.toggleExpandedState(node, options); + this._renderNode(node); }, this)); - this.render(); + // this.render(); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 7a82a2eeb..cfde7aaac 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -150,6 +150,7 @@ this.tree = []; this.nodes = []; + this.initialized = false; if (options.data) { if (typeof options.data === 'string') { @@ -321,27 +322,34 @@ var target = $(event.target); var node = this.findNode(target); if (!node || node.state.disabled) return; - + var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { this.toggleExpandedState(node, _default.options); - this.render(); + // this.render(); + // this._expandNode(node); + this._renderNode(node); } else if ((classList.indexOf('check-icon') !== -1)) { this.toggleCheckedState(node, _default.options); this.render(); + // TODO this._checkNode(); } else { if (node.selectable) { this.toggleSelectedState(node, _default.options); + this.render(); + // TODO this._selectNode(node); } else { this.toggleExpandedState(node, _default.options); + // this._expandNode(node); + this._renderNode(node); } - this.render(); + // this.render(); } }; @@ -386,6 +394,7 @@ // Collapse child nodes if (node.nodes && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { + console.log('recurse children') this.setExpandedState(node, false, options); }, this)); } @@ -484,136 +493,186 @@ Tree.prototype.render = function () { + console.log('RENDER'); + if (!this.initialized) { // Setup first time only components - this.$element.addClass(pluginName); - this.$wrapper = $(this.template.list); + this.$wrapper = $(this.template.tree); + this.$element.empty() + .addClass(pluginName) + .append(this.$wrapper); this.injectStyle(); this.initialized = true; } - this.$element.empty().append(this.$wrapper.empty()); + if (!this.tree) return; - // Build tree - this.buildTree(this.tree, 0); + $.each(this.tree, $.proxy(function addRootNodes(id, node) { + node.level = 1; + this._renderNode(node); + }, this)); }; - // Starting from the root node, and recursing down the - // structure we build the tree one node at a time - Tree.prototype.buildTree = function (nodes, level) { + // Creates a new node element from template and + // ensures the template is inserted at the correct position + Tree.prototype._newNodeEl = function (pEl) { - if (!nodes) return; - level += 1; + var $el = $(this.template.node); + + if (pEl) { + console.log('insert'); + this.$wrapper.children().eq(pEl.index()).after($el); + } + else { + console.log('append'); + this.$wrapper.append($el); + } - var _this = this; - $.each(nodes, function addNodes(id, node) { - - var treeItem = $(_this.template.item) - .addClass('node-' + _this.elementId) - .addClass(node.state.checked ? 'node-checked' : '') - .addClass(node.state.disabled ? 'node-disabled': '') - .addClass(node.state.selected ? 'node-selected' : '') - .addClass(node.searchResult ? 'search-result' : '') - .attr('data-nodeid', node.nodeId) - .attr('style', _this.buildStyleOverride(node)); - - // Add indent/spacer to mimic tree structure - for (var i = 0; i < (level - 1); i++) { - treeItem.append(_this.template.indent); - } + return $el; + }; - // Add expand, collapse or empty spacer icons - var classList = []; - if (node.nodes) { - classList.push('expand-icon'); - if (node.state.expanded) { - classList.push(_this.options.collapseIcon); - } - else { - classList.push(_this.options.expandIcon); - } - } - else { - classList.push(_this.options.emptyIcon); + Tree.prototype._collapseNode = function (node) { + if (!node.nodes) return; + console.log('collapseNode - ' + node.text); + $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { + this._collapseNode(node); + if (node.$el) { + node.$el.remove(); + node.$el = null; } + }, this)); + }; - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + Tree.prototype._expandNode = function (node) { + if (!node.nodes) return; + console.log('expandNode - ' + node.text); + var $pEl = node.$el; + $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, $pEl); + $pEl = childNode.$el; + }, this)); + } + + Tree.prototype._renderNode = function (node, pEl) { + console.log('renderNode - ' + node.text); + if (!node) return; + // console.log(node); + if (!node.$el) { + node.$el = this._newNodeEl(pEl); + } + else { + // TODO Don't blanket empty, eval each action + node.$el.empty(); + } - // Add node icon - if (_this.options.showIcon) { - - var classList = ['node-icon']; + node.$el + .addClass('node-' + this.elementId) + .addClass(node.state.checked ? 'node-checked' : '') + .addClass(node.state.disabled ? 'node-disabled': '') + .addClass(node.state.selected ? 'node-selected' : '') + .addClass(node.searchResult ? 'search-result' : '') + .attr('data-nodeid', node.nodeId) + .attr('style', this.buildStyleOverride(node)); - classList.push(node.icon || _this.options.nodeIcon); - if (node.state.selected) { - classList.pop(); - classList.push(node.selectedIcon || _this.options.selectedIcon || - node.icon || _this.options.nodeIcon); - } - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + // Add indent/spacer to mimic tree structure + for (var i = 0; i < (node.level - 1); i++) { + node.$el.append(this.template.indent); + } + + // Add expand, collapse or empty spacer icons + var classList = []; + if (node.nodes) { + classList.push('expand-icon'); + if (node.state.expanded) { + classList.push(this.options.collapseIcon); + } + else { + classList.push(this.options.expandIcon); } + } + else { + classList.push(this.options.emptyIcon); + } - // Add check / unchecked icon - if (_this.options.showCheckbox) { + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); - var classList = ['check-icon']; - if (node.state.checked) { - classList.push(_this.options.checkedIcon); - } - else { - classList.push(_this.options.uncheckedIcon); - } - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + // Add node icon + if (this.options.showIcon) { + + var classList = ['node-icon']; + + classList.push(node.icon || this.options.nodeIcon); + if (node.state.selected) { + classList.pop(); + classList.push(node.selectedIcon || this.options.selectedIcon || + node.icon || this.options.nodeIcon); } - // Add text - if (_this.options.enableLinks) { - // Add hyperlink - treeItem - .append($(_this.template.link) - .attr('href', node.href) - .append(node.text) - ); + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add check / unchecked icon + if (this.options.showCheckbox) { + + var classList = ['check-icon']; + if (node.state.checked) { + classList.push(this.options.checkedIcon); } else { - // otherwise just text - treeItem - .append(node.text); + classList.push(this.options.uncheckedIcon); } - // Add tags as badges - if (_this.options.showTags && node.tags) { - $.each(node.tags, function addTag(id, tag) { - treeItem - .append($(_this.template.badge) - .append(tag) - ); - }); - } + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add text + if (this.options.enableLinks) { + // Add hyperlink + node.$el + .append($(this.template.link) + .attr('href', node.href) + .append(node.text) + ); + } + else { + // otherwise just text + node.$el + .append(node.text); + } - // Add item to the tree - _this.$wrapper.append(treeItem); + // Add tags as badges + if (this.options.showTags && node.tags) { + $.each(node.tags, $.proxy(function addTag(id, tag) { + node.$el + .append($(this.template.badge) + .append(tag) + ); + }, this)); + } - // Recursively add child ndoes - if (node.nodes && node.state.expanded && !node.state.disabled) { - return _this.buildTree(node.nodes, level); - } - }); + // Recursively add child ndoes + if (node.nodes && node.state.expanded && !node.state.disabled) { + this._expandNode(node); + } + else { + this._collapseNode(node); + } }; // Define any node level style override for @@ -687,8 +746,8 @@ }; Tree.prototype.template = { - list: '
            ', - item: '
          • ', + tree: '
              ', + node: '
            • ', indent: '', icon: '', link: '', @@ -841,12 +900,9 @@ @param {optional Object} options */ Tree.prototype.collapseAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.expanded'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, false, options); - }, this)); - - this.render(); + options = $.extend({}, _default.options, options); + options.levels = options.levels || 999; + this.collapseNode(this.tree, options); }; /** @@ -855,11 +911,11 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { + options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, false, options); + this._renderNode(node); }, this)); - - this.render(); }; /** @@ -868,18 +924,8 @@ */ Tree.prototype.expandAll = function (options) { options = $.extend({}, _default.options, options); - - if (options && options.levels) { - this.expandLevels(this.tree, options.levels, options); - } - else { - var identifiers = this.findNodes('false', 'g', 'state.expanded'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, true, options); - }, this)); - } - - this.render(); + options.levels = options.levels || 999; + this.expandNode(this.tree, options); }; /** @@ -888,23 +934,22 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { + options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, true, options); - if (node.nodes && (options && options.levels)) { - this.expandLevels(node.nodes, options.levels-1, options); + if (node.nodes) { + this._expandLevels(node.nodes, options.levels-1, options); } + this._renderNode(node); }, this)); - - this.render(); }; - Tree.prototype.expandLevels = function (nodes, level, options) { - options = $.extend({}, _default.options, options); - + Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { + console.log('test - ' + node.text); this.setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { - this.expandLevels(node.nodes, level-1, options); + this._expandLevels(node.nodes, level-1, options); } }, this)); }; @@ -916,14 +961,14 @@ */ Tree.prototype.revealNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - var parentNode = this.getParent(node); - while (parentNode) { + var parentNode = node; + var tmpNode; + while (tmpNode = this.getParent(parentNode)) { + parentNode = tmpNode; this.setExpandedState(parentNode, true, options); - parentNode = this.getParent(parentNode); }; + this._renderNode(parentNode); }, this)); - - this.render(); }; /** @@ -934,9 +979,10 @@ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.toggleExpandedState(node, options); + this._renderNode(node); }, this)); - this.render(); + // this.render(); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 7a82a2eeb..cfde7aaac 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -150,6 +150,7 @@ this.tree = []; this.nodes = []; + this.initialized = false; if (options.data) { if (typeof options.data === 'string') { @@ -321,27 +322,34 @@ var target = $(event.target); var node = this.findNode(target); if (!node || node.state.disabled) return; - + var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { this.toggleExpandedState(node, _default.options); - this.render(); + // this.render(); + // this._expandNode(node); + this._renderNode(node); } else if ((classList.indexOf('check-icon') !== -1)) { this.toggleCheckedState(node, _default.options); this.render(); + // TODO this._checkNode(); } else { if (node.selectable) { this.toggleSelectedState(node, _default.options); + this.render(); + // TODO this._selectNode(node); } else { this.toggleExpandedState(node, _default.options); + // this._expandNode(node); + this._renderNode(node); } - this.render(); + // this.render(); } }; @@ -386,6 +394,7 @@ // Collapse child nodes if (node.nodes && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { + console.log('recurse children') this.setExpandedState(node, false, options); }, this)); } @@ -484,136 +493,186 @@ Tree.prototype.render = function () { + console.log('RENDER'); + if (!this.initialized) { // Setup first time only components - this.$element.addClass(pluginName); - this.$wrapper = $(this.template.list); + this.$wrapper = $(this.template.tree); + this.$element.empty() + .addClass(pluginName) + .append(this.$wrapper); this.injectStyle(); this.initialized = true; } - this.$element.empty().append(this.$wrapper.empty()); + if (!this.tree) return; - // Build tree - this.buildTree(this.tree, 0); + $.each(this.tree, $.proxy(function addRootNodes(id, node) { + node.level = 1; + this._renderNode(node); + }, this)); }; - // Starting from the root node, and recursing down the - // structure we build the tree one node at a time - Tree.prototype.buildTree = function (nodes, level) { + // Creates a new node element from template and + // ensures the template is inserted at the correct position + Tree.prototype._newNodeEl = function (pEl) { - if (!nodes) return; - level += 1; + var $el = $(this.template.node); + + if (pEl) { + console.log('insert'); + this.$wrapper.children().eq(pEl.index()).after($el); + } + else { + console.log('append'); + this.$wrapper.append($el); + } - var _this = this; - $.each(nodes, function addNodes(id, node) { - - var treeItem = $(_this.template.item) - .addClass('node-' + _this.elementId) - .addClass(node.state.checked ? 'node-checked' : '') - .addClass(node.state.disabled ? 'node-disabled': '') - .addClass(node.state.selected ? 'node-selected' : '') - .addClass(node.searchResult ? 'search-result' : '') - .attr('data-nodeid', node.nodeId) - .attr('style', _this.buildStyleOverride(node)); - - // Add indent/spacer to mimic tree structure - for (var i = 0; i < (level - 1); i++) { - treeItem.append(_this.template.indent); - } + return $el; + }; - // Add expand, collapse or empty spacer icons - var classList = []; - if (node.nodes) { - classList.push('expand-icon'); - if (node.state.expanded) { - classList.push(_this.options.collapseIcon); - } - else { - classList.push(_this.options.expandIcon); - } - } - else { - classList.push(_this.options.emptyIcon); + Tree.prototype._collapseNode = function (node) { + if (!node.nodes) return; + console.log('collapseNode - ' + node.text); + $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { + this._collapseNode(node); + if (node.$el) { + node.$el.remove(); + node.$el = null; } + }, this)); + }; - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + Tree.prototype._expandNode = function (node) { + if (!node.nodes) return; + console.log('expandNode - ' + node.text); + var $pEl = node.$el; + $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, $pEl); + $pEl = childNode.$el; + }, this)); + } + + Tree.prototype._renderNode = function (node, pEl) { + console.log('renderNode - ' + node.text); + if (!node) return; + // console.log(node); + if (!node.$el) { + node.$el = this._newNodeEl(pEl); + } + else { + // TODO Don't blanket empty, eval each action + node.$el.empty(); + } - // Add node icon - if (_this.options.showIcon) { - - var classList = ['node-icon']; + node.$el + .addClass('node-' + this.elementId) + .addClass(node.state.checked ? 'node-checked' : '') + .addClass(node.state.disabled ? 'node-disabled': '') + .addClass(node.state.selected ? 'node-selected' : '') + .addClass(node.searchResult ? 'search-result' : '') + .attr('data-nodeid', node.nodeId) + .attr('style', this.buildStyleOverride(node)); - classList.push(node.icon || _this.options.nodeIcon); - if (node.state.selected) { - classList.pop(); - classList.push(node.selectedIcon || _this.options.selectedIcon || - node.icon || _this.options.nodeIcon); - } - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + // Add indent/spacer to mimic tree structure + for (var i = 0; i < (node.level - 1); i++) { + node.$el.append(this.template.indent); + } + + // Add expand, collapse or empty spacer icons + var classList = []; + if (node.nodes) { + classList.push('expand-icon'); + if (node.state.expanded) { + classList.push(this.options.collapseIcon); + } + else { + classList.push(this.options.expandIcon); } + } + else { + classList.push(this.options.emptyIcon); + } - // Add check / unchecked icon - if (_this.options.showCheckbox) { + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); - var classList = ['check-icon']; - if (node.state.checked) { - classList.push(_this.options.checkedIcon); - } - else { - classList.push(_this.options.uncheckedIcon); - } - treeItem - .append($(_this.template.icon) - .addClass(classList.join(' ')) - ); + // Add node icon + if (this.options.showIcon) { + + var classList = ['node-icon']; + + classList.push(node.icon || this.options.nodeIcon); + if (node.state.selected) { + classList.pop(); + classList.push(node.selectedIcon || this.options.selectedIcon || + node.icon || this.options.nodeIcon); } - // Add text - if (_this.options.enableLinks) { - // Add hyperlink - treeItem - .append($(_this.template.link) - .attr('href', node.href) - .append(node.text) - ); + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add check / unchecked icon + if (this.options.showCheckbox) { + + var classList = ['check-icon']; + if (node.state.checked) { + classList.push(this.options.checkedIcon); } else { - // otherwise just text - treeItem - .append(node.text); + classList.push(this.options.uncheckedIcon); } - // Add tags as badges - if (_this.options.showTags && node.tags) { - $.each(node.tags, function addTag(id, tag) { - treeItem - .append($(_this.template.badge) - .append(tag) - ); - }); - } + node.$el + .append($(this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add text + if (this.options.enableLinks) { + // Add hyperlink + node.$el + .append($(this.template.link) + .attr('href', node.href) + .append(node.text) + ); + } + else { + // otherwise just text + node.$el + .append(node.text); + } - // Add item to the tree - _this.$wrapper.append(treeItem); + // Add tags as badges + if (this.options.showTags && node.tags) { + $.each(node.tags, $.proxy(function addTag(id, tag) { + node.$el + .append($(this.template.badge) + .append(tag) + ); + }, this)); + } - // Recursively add child ndoes - if (node.nodes && node.state.expanded && !node.state.disabled) { - return _this.buildTree(node.nodes, level); - } - }); + // Recursively add child ndoes + if (node.nodes && node.state.expanded && !node.state.disabled) { + this._expandNode(node); + } + else { + this._collapseNode(node); + } }; // Define any node level style override for @@ -687,8 +746,8 @@ }; Tree.prototype.template = { - list: '
                ', - item: '
              • ', + tree: '
                  ', + node: '
                • ', indent: '', icon: '', link: '', @@ -841,12 +900,9 @@ @param {optional Object} options */ Tree.prototype.collapseAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.expanded'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, false, options); - }, this)); - - this.render(); + options = $.extend({}, _default.options, options); + options.levels = options.levels || 999; + this.collapseNode(this.tree, options); }; /** @@ -855,11 +911,11 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { + options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, false, options); + this._renderNode(node); }, this)); - - this.render(); }; /** @@ -868,18 +924,8 @@ */ Tree.prototype.expandAll = function (options) { options = $.extend({}, _default.options, options); - - if (options && options.levels) { - this.expandLevels(this.tree, options.levels, options); - } - else { - var identifiers = this.findNodes('false', 'g', 'state.expanded'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, true, options); - }, this)); - } - - this.render(); + options.levels = options.levels || 999; + this.expandNode(this.tree, options); }; /** @@ -888,23 +934,22 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { + options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, true, options); - if (node.nodes && (options && options.levels)) { - this.expandLevels(node.nodes, options.levels-1, options); + if (node.nodes) { + this._expandLevels(node.nodes, options.levels-1, options); } + this._renderNode(node); }, this)); - - this.render(); }; - Tree.prototype.expandLevels = function (nodes, level, options) { - options = $.extend({}, _default.options, options); - + Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { + console.log('test - ' + node.text); this.setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { - this.expandLevels(node.nodes, level-1, options); + this._expandLevels(node.nodes, level-1, options); } }, this)); }; @@ -916,14 +961,14 @@ */ Tree.prototype.revealNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - var parentNode = this.getParent(node); - while (parentNode) { + var parentNode = node; + var tmpNode; + while (tmpNode = this.getParent(parentNode)) { + parentNode = tmpNode; this.setExpandedState(parentNode, true, options); - parentNode = this.getParent(parentNode); }; + this._renderNode(parentNode); }, this)); - - this.render(); }; /** @@ -934,9 +979,10 @@ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.toggleExpandedState(node, options); + this._renderNode(node); }, this)); - this.render(); + // this.render(); }; From 9b6758c09bd02115768fd861c48c9f4844bce592 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 20 Jun 2015 20:52:56 +0100 Subject: [PATCH 02/52] Node selected update to render state changes via css only #76 - The class node-selected is added via setSelectedState - Removed inline style that sets color + background-color based on selected state - Updated injected css to use options selectedColor + selectedBackColor - Allows of user override via .css resource --- dist/bootstrap-treeview.min.css | 2 +- dist/bootstrap-treeview.min.js | 2 +- public/css/bootstrap-treeview.css | 9 ++ public/index.html | 2 +- public/js/bootstrap-treeview.js | 170 +++++++++++++++++++----------- src/css/bootstrap-treeview.css | 9 ++ src/js/bootstrap-treeview.js | 170 +++++++++++++++++++----------- tests/lib/bootstrap-treeview.css | 9 ++ tests/lib/bootstrap-treeview.js | 170 +++++++++++++++++++----------- 9 files changed, 351 insertions(+), 192 deletions(-) diff --git a/dist/bootstrap-treeview.min.css b/dist/bootstrap-treeview.min.css index 57a348a87..ca804945b 100644 --- a/dist/bootstrap-treeview.min.css +++ b/dist/bootstrap-treeview.min.css @@ -1 +1 @@ -.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed} \ No newline at end of file +.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}.treeview .node-selected{background-color:#428bca!important;color:#FFF!important} \ No newline at end of file diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index fe404da84..613c3dc9a 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):d.selectable?(this.toggleSelectedState(d,f.options),this.render()):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype.toggleSelectedState=function(a,b){a&&this.setSelectedState(a,!a.state.selected,b)},g.prototype.setSelectedState=function(b,c,d){c!==b.state.selected&&(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this.setSelectedState(b,!1,d)},this)),b.state.selected=!0,d.silent||this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,d.silent||this.$element.trigger("nodeUnselected",a.extend(!0,{},b))))},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this.setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).addClass(b.state.checked?"node-checked":"").addClass(b.state.disabled?"node-disabled":"").addClass(b.state.selected?"node-selected":"").addClass(b.searchResult?"search-result":"").attr("data-nodeid",b.nodeId).attr("style",this.buildStyleOverride(b));for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";return this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.css+a},g.prototype.template={tree:'
                    ',node:'
                  • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!0,b)},this)),this.render()},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleSelectedState(a,b)},this)),this.render()},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):d.selectable?this._toggleSelectedState(d,f.options):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c!==b.state.selected?(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this):void 0},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this._setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.state.checked?b.$el.addClass("node-checked"):b.$el.removeClass("node-checked"),b.state.disabled?b.$el.addClass("node-disabled"):b.$el.removeClass("node-disabled"),this._setSelectedState(b,b.state.selected),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                      ',node:'
                    • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/css/bootstrap-treeview.css b/public/css/bootstrap-treeview.css index 23c6cf066..d62bf7c7b 100644 --- a/public/css/bootstrap-treeview.css +++ b/public/css/bootstrap-treeview.css @@ -34,4 +34,13 @@ .treeview .node-disabled { color: silver; cursor: not-allowed; +} + +/* + Only valid when either options selectedColor or + selectedBackColor are left undefined +*/ +.treeview .node-selected { + background-color: #428bca !important; + color: #FFFFFF !important; } \ No newline at end of file diff --git a/public/index.html b/public/index.html index 6f23ccd23..979ad3e3f 100644 --- a/public/index.html +++ b/public/index.html @@ -3,7 +3,7 @@ Bootstrap Tree View - +
                      diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index cfde7aaac..25bfcd008 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -327,8 +327,6 @@ if ((classList.indexOf('expand-icon') !== -1)) { this.toggleExpandedState(node, _default.options); - // this.render(); - // this._expandNode(node); this._renderNode(node); } else if ((classList.indexOf('check-icon') !== -1)) { @@ -340,16 +338,11 @@ else { if (node.selectable) { - this.toggleSelectedState(node, _default.options); - this.render(); - // TODO this._selectNode(node); + this._toggleSelectedState(node, _default.options); } else { this.toggleExpandedState(node, _default.options); - // this._expandNode(node); this._renderNode(node); } - - // this.render(); } }; @@ -401,12 +394,13 @@ } }; - Tree.prototype.toggleSelectedState = function (node, options) { + Tree.prototype._toggleSelectedState = function (node, options) { if (!node) return; - this.setSelectedState(node, !node.state.selected, options); + this._setSelectedState(node, !node.state.selected, options); + return this; }; - Tree.prototype.setSelectedState = function (node, state, options) { + Tree.prototype._setSelectedState = function (node, state, options) { if (state === node.state.selected) return; @@ -415,24 +409,36 @@ // If multiSelect false, unselect previously selected if (!this.options.multiSelect) { $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); }, this)); } - // Continue selecting node + // Set note state node.state.selected = true; - if (!options.silent) { + + // Add class + node.$el.addClass('node-selected'); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeSelected', $.extend(true, {}, node)); } } else { - // Unselect node + // Set node state node.state.selected = false; - if (!options.silent) { + + // Add class + node.$el.removeClass('node-selected'); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); } } + + return this; }; Tree.prototype.toggleCheckedState = function (node, options) { @@ -474,7 +480,7 @@ // Disable all other states this.setExpandedState(node, false, options); - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); this.setCheckedState(node, false, options); if (!options.silent) { @@ -536,6 +542,7 @@ Tree.prototype._collapseNode = function (node) { if (!node.nodes) return; + console.log('collapseNode - ' + node.text); $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { this._collapseNode(node); @@ -548,6 +555,7 @@ Tree.prototype._expandNode = function (node) { if (!node.nodes) return; + console.log('expandNode - ' + node.text); var $pEl = node.$el; $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { @@ -555,7 +563,7 @@ this._renderNode(childNode, $pEl); $pEl = childNode.$el; }, this)); - } + }; Tree.prototype._renderNode = function (node, pEl) { console.log('renderNode - ' + node.text); @@ -563,21 +571,49 @@ // console.log(node); if (!node.$el) { + + // New node, needs a new element node.$el = this._newNodeEl(pEl); + + // One time setup + node.$el + .addClass('node-' + this.elementId) + .attr('data-nodeid', node.nodeId); } else { // TODO Don't blanket empty, eval each action node.$el.empty(); } - node.$el - .addClass('node-' + this.elementId) - .addClass(node.state.checked ? 'node-checked' : '') - .addClass(node.state.disabled ? 'node-disabled': '') - .addClass(node.state.selected ? 'node-selected' : '') - .addClass(node.searchResult ? 'search-result' : '') - .attr('data-nodeid', node.nodeId) - .attr('style', this.buildStyleOverride(node)); + // Set checked state + if (node.state.checked) { + node.$el.addClass('node-checked'); + } + else { + node.$el.removeClass('node-checked'); + } + + // Set disabled state + if (node.state.disabled) { + node.$el.addClass('node-disabled'); + } + else { + node.$el.removeClass('node-disabled'); + } + + // Set selected state + this._setSelectedState(node, node.state.selected); + + // Set search result state + if (node.searchResult) { + node.$el.addClass('node-result'); + } + else { + node.$el.removeClass('node-result'); + } + + // Set state based style overrides + // node.$el.attr('style', this.buildStyleOverride(node)); // Add indent/spacer to mimic tree structure @@ -678,34 +714,34 @@ // Define any node level style override for // 1. selectedNode // 2. node|data assigned color overrides - Tree.prototype.buildStyleOverride = function (node) { - - if (node.state.disabled) return ''; - - var color = node.color; - var backColor = node.backColor; - - if (this.options.highlightSelected && node.state.selected) { - if (this.options.selectedColor) { - color = this.options.selectedColor; - } - if (this.options.selectedBackColor) { - backColor = this.options.selectedBackColor; - } - } - - if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { - if (this.options.searchResultColor) { - color = this.options.searchResultColor; - } - if (this.options.searchResultBackColor) { - backColor = this.options.searchResultBackColor; - } - } - - return 'color:' + color + - ';background-color:' + backColor + ';'; - }; + // Tree.prototype.buildStyleOverride = function (node) { + + // if (node.state.disabled) return ''; + + // var color = node.color; + // var backColor = node.backColor; + + // // if (this.options.highlightSelected && node.state.selected) { + // // if (this.options.selectedColor) { + // // color = this.options.selectedColor; + // // } + // // if (this.options.selectedBackColor) { + // // backColor = this.options.selectedBackColor; + // // } + // // } + + // if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { + // if (this.options.searchResultColor) { + // color = this.options.searchResultColor; + // } + // if (this.options.searchResultBackColor) { + // backColor = this.options.searchResultBackColor; + // } + // } + + // // return 'color:' + color + + // // ';background-color:' + backColor + ';'; + // }; // Add inline style into head Tree.prototype.injectStyle = function () { @@ -742,6 +778,20 @@ '}'; } + if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { + + var innerStyle = '' + if (this.options.selectedColor) { + innerStyle += 'color:' + this.options.selectedColor + ';'; + } + if (this.options.selectedBackColor) { + innerStyle += 'background-color:' + this.options.selectedBackColor + ';'; + } + + style += '.node-' + this.elementId + '.node-selected{' + innerStyle + '}'; + style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; + } + return this.css + style; }; @@ -862,10 +912,8 @@ */ Tree.prototype.selectNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setSelectedState(node, true, options); + this._setSelectedState(node, true, options); }, this)); - - this.render(); }; /** @@ -875,10 +923,8 @@ */ Tree.prototype.unselectNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); }, this)); - - this.render(); }; /** @@ -888,10 +934,8 @@ */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleSelectedState(node, options); + this._toggleSelectedState(node, options); }, this)); - - this.render(); }; diff --git a/src/css/bootstrap-treeview.css b/src/css/bootstrap-treeview.css index 23c6cf066..d62bf7c7b 100644 --- a/src/css/bootstrap-treeview.css +++ b/src/css/bootstrap-treeview.css @@ -34,4 +34,13 @@ .treeview .node-disabled { color: silver; cursor: not-allowed; +} + +/* + Only valid when either options selectedColor or + selectedBackColor are left undefined +*/ +.treeview .node-selected { + background-color: #428bca !important; + color: #FFFFFF !important; } \ No newline at end of file diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index cfde7aaac..25bfcd008 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -327,8 +327,6 @@ if ((classList.indexOf('expand-icon') !== -1)) { this.toggleExpandedState(node, _default.options); - // this.render(); - // this._expandNode(node); this._renderNode(node); } else if ((classList.indexOf('check-icon') !== -1)) { @@ -340,16 +338,11 @@ else { if (node.selectable) { - this.toggleSelectedState(node, _default.options); - this.render(); - // TODO this._selectNode(node); + this._toggleSelectedState(node, _default.options); } else { this.toggleExpandedState(node, _default.options); - // this._expandNode(node); this._renderNode(node); } - - // this.render(); } }; @@ -401,12 +394,13 @@ } }; - Tree.prototype.toggleSelectedState = function (node, options) { + Tree.prototype._toggleSelectedState = function (node, options) { if (!node) return; - this.setSelectedState(node, !node.state.selected, options); + this._setSelectedState(node, !node.state.selected, options); + return this; }; - Tree.prototype.setSelectedState = function (node, state, options) { + Tree.prototype._setSelectedState = function (node, state, options) { if (state === node.state.selected) return; @@ -415,24 +409,36 @@ // If multiSelect false, unselect previously selected if (!this.options.multiSelect) { $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); }, this)); } - // Continue selecting node + // Set note state node.state.selected = true; - if (!options.silent) { + + // Add class + node.$el.addClass('node-selected'); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeSelected', $.extend(true, {}, node)); } } else { - // Unselect node + // Set node state node.state.selected = false; - if (!options.silent) { + + // Add class + node.$el.removeClass('node-selected'); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); } } + + return this; }; Tree.prototype.toggleCheckedState = function (node, options) { @@ -474,7 +480,7 @@ // Disable all other states this.setExpandedState(node, false, options); - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); this.setCheckedState(node, false, options); if (!options.silent) { @@ -536,6 +542,7 @@ Tree.prototype._collapseNode = function (node) { if (!node.nodes) return; + console.log('collapseNode - ' + node.text); $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { this._collapseNode(node); @@ -548,6 +555,7 @@ Tree.prototype._expandNode = function (node) { if (!node.nodes) return; + console.log('expandNode - ' + node.text); var $pEl = node.$el; $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { @@ -555,7 +563,7 @@ this._renderNode(childNode, $pEl); $pEl = childNode.$el; }, this)); - } + }; Tree.prototype._renderNode = function (node, pEl) { console.log('renderNode - ' + node.text); @@ -563,21 +571,49 @@ // console.log(node); if (!node.$el) { + + // New node, needs a new element node.$el = this._newNodeEl(pEl); + + // One time setup + node.$el + .addClass('node-' + this.elementId) + .attr('data-nodeid', node.nodeId); } else { // TODO Don't blanket empty, eval each action node.$el.empty(); } - node.$el - .addClass('node-' + this.elementId) - .addClass(node.state.checked ? 'node-checked' : '') - .addClass(node.state.disabled ? 'node-disabled': '') - .addClass(node.state.selected ? 'node-selected' : '') - .addClass(node.searchResult ? 'search-result' : '') - .attr('data-nodeid', node.nodeId) - .attr('style', this.buildStyleOverride(node)); + // Set checked state + if (node.state.checked) { + node.$el.addClass('node-checked'); + } + else { + node.$el.removeClass('node-checked'); + } + + // Set disabled state + if (node.state.disabled) { + node.$el.addClass('node-disabled'); + } + else { + node.$el.removeClass('node-disabled'); + } + + // Set selected state + this._setSelectedState(node, node.state.selected); + + // Set search result state + if (node.searchResult) { + node.$el.addClass('node-result'); + } + else { + node.$el.removeClass('node-result'); + } + + // Set state based style overrides + // node.$el.attr('style', this.buildStyleOverride(node)); // Add indent/spacer to mimic tree structure @@ -678,34 +714,34 @@ // Define any node level style override for // 1. selectedNode // 2. node|data assigned color overrides - Tree.prototype.buildStyleOverride = function (node) { - - if (node.state.disabled) return ''; - - var color = node.color; - var backColor = node.backColor; - - if (this.options.highlightSelected && node.state.selected) { - if (this.options.selectedColor) { - color = this.options.selectedColor; - } - if (this.options.selectedBackColor) { - backColor = this.options.selectedBackColor; - } - } - - if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { - if (this.options.searchResultColor) { - color = this.options.searchResultColor; - } - if (this.options.searchResultBackColor) { - backColor = this.options.searchResultBackColor; - } - } - - return 'color:' + color + - ';background-color:' + backColor + ';'; - }; + // Tree.prototype.buildStyleOverride = function (node) { + + // if (node.state.disabled) return ''; + + // var color = node.color; + // var backColor = node.backColor; + + // // if (this.options.highlightSelected && node.state.selected) { + // // if (this.options.selectedColor) { + // // color = this.options.selectedColor; + // // } + // // if (this.options.selectedBackColor) { + // // backColor = this.options.selectedBackColor; + // // } + // // } + + // if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { + // if (this.options.searchResultColor) { + // color = this.options.searchResultColor; + // } + // if (this.options.searchResultBackColor) { + // backColor = this.options.searchResultBackColor; + // } + // } + + // // return 'color:' + color + + // // ';background-color:' + backColor + ';'; + // }; // Add inline style into head Tree.prototype.injectStyle = function () { @@ -742,6 +778,20 @@ '}'; } + if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { + + var innerStyle = '' + if (this.options.selectedColor) { + innerStyle += 'color:' + this.options.selectedColor + ';'; + } + if (this.options.selectedBackColor) { + innerStyle += 'background-color:' + this.options.selectedBackColor + ';'; + } + + style += '.node-' + this.elementId + '.node-selected{' + innerStyle + '}'; + style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; + } + return this.css + style; }; @@ -862,10 +912,8 @@ */ Tree.prototype.selectNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setSelectedState(node, true, options); + this._setSelectedState(node, true, options); }, this)); - - this.render(); }; /** @@ -875,10 +923,8 @@ */ Tree.prototype.unselectNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); }, this)); - - this.render(); }; /** @@ -888,10 +934,8 @@ */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleSelectedState(node, options); + this._toggleSelectedState(node, options); }, this)); - - this.render(); }; diff --git a/tests/lib/bootstrap-treeview.css b/tests/lib/bootstrap-treeview.css index 23c6cf066..d62bf7c7b 100644 --- a/tests/lib/bootstrap-treeview.css +++ b/tests/lib/bootstrap-treeview.css @@ -34,4 +34,13 @@ .treeview .node-disabled { color: silver; cursor: not-allowed; +} + +/* + Only valid when either options selectedColor or + selectedBackColor are left undefined +*/ +.treeview .node-selected { + background-color: #428bca !important; + color: #FFFFFF !important; } \ No newline at end of file diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index cfde7aaac..25bfcd008 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -327,8 +327,6 @@ if ((classList.indexOf('expand-icon') !== -1)) { this.toggleExpandedState(node, _default.options); - // this.render(); - // this._expandNode(node); this._renderNode(node); } else if ((classList.indexOf('check-icon') !== -1)) { @@ -340,16 +338,11 @@ else { if (node.selectable) { - this.toggleSelectedState(node, _default.options); - this.render(); - // TODO this._selectNode(node); + this._toggleSelectedState(node, _default.options); } else { this.toggleExpandedState(node, _default.options); - // this._expandNode(node); this._renderNode(node); } - - // this.render(); } }; @@ -401,12 +394,13 @@ } }; - Tree.prototype.toggleSelectedState = function (node, options) { + Tree.prototype._toggleSelectedState = function (node, options) { if (!node) return; - this.setSelectedState(node, !node.state.selected, options); + this._setSelectedState(node, !node.state.selected, options); + return this; }; - Tree.prototype.setSelectedState = function (node, state, options) { + Tree.prototype._setSelectedState = function (node, state, options) { if (state === node.state.selected) return; @@ -415,24 +409,36 @@ // If multiSelect false, unselect previously selected if (!this.options.multiSelect) { $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); }, this)); } - // Continue selecting node + // Set note state node.state.selected = true; - if (!options.silent) { + + // Add class + node.$el.addClass('node-selected'); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeSelected', $.extend(true, {}, node)); } } else { - // Unselect node + // Set node state node.state.selected = false; - if (!options.silent) { + + // Add class + node.$el.removeClass('node-selected'); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); } } + + return this; }; Tree.prototype.toggleCheckedState = function (node, options) { @@ -474,7 +480,7 @@ // Disable all other states this.setExpandedState(node, false, options); - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); this.setCheckedState(node, false, options); if (!options.silent) { @@ -536,6 +542,7 @@ Tree.prototype._collapseNode = function (node) { if (!node.nodes) return; + console.log('collapseNode - ' + node.text); $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { this._collapseNode(node); @@ -548,6 +555,7 @@ Tree.prototype._expandNode = function (node) { if (!node.nodes) return; + console.log('expandNode - ' + node.text); var $pEl = node.$el; $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { @@ -555,7 +563,7 @@ this._renderNode(childNode, $pEl); $pEl = childNode.$el; }, this)); - } + }; Tree.prototype._renderNode = function (node, pEl) { console.log('renderNode - ' + node.text); @@ -563,21 +571,49 @@ // console.log(node); if (!node.$el) { + + // New node, needs a new element node.$el = this._newNodeEl(pEl); + + // One time setup + node.$el + .addClass('node-' + this.elementId) + .attr('data-nodeid', node.nodeId); } else { // TODO Don't blanket empty, eval each action node.$el.empty(); } - node.$el - .addClass('node-' + this.elementId) - .addClass(node.state.checked ? 'node-checked' : '') - .addClass(node.state.disabled ? 'node-disabled': '') - .addClass(node.state.selected ? 'node-selected' : '') - .addClass(node.searchResult ? 'search-result' : '') - .attr('data-nodeid', node.nodeId) - .attr('style', this.buildStyleOverride(node)); + // Set checked state + if (node.state.checked) { + node.$el.addClass('node-checked'); + } + else { + node.$el.removeClass('node-checked'); + } + + // Set disabled state + if (node.state.disabled) { + node.$el.addClass('node-disabled'); + } + else { + node.$el.removeClass('node-disabled'); + } + + // Set selected state + this._setSelectedState(node, node.state.selected); + + // Set search result state + if (node.searchResult) { + node.$el.addClass('node-result'); + } + else { + node.$el.removeClass('node-result'); + } + + // Set state based style overrides + // node.$el.attr('style', this.buildStyleOverride(node)); // Add indent/spacer to mimic tree structure @@ -678,34 +714,34 @@ // Define any node level style override for // 1. selectedNode // 2. node|data assigned color overrides - Tree.prototype.buildStyleOverride = function (node) { - - if (node.state.disabled) return ''; - - var color = node.color; - var backColor = node.backColor; - - if (this.options.highlightSelected && node.state.selected) { - if (this.options.selectedColor) { - color = this.options.selectedColor; - } - if (this.options.selectedBackColor) { - backColor = this.options.selectedBackColor; - } - } - - if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { - if (this.options.searchResultColor) { - color = this.options.searchResultColor; - } - if (this.options.searchResultBackColor) { - backColor = this.options.searchResultBackColor; - } - } - - return 'color:' + color + - ';background-color:' + backColor + ';'; - }; + // Tree.prototype.buildStyleOverride = function (node) { + + // if (node.state.disabled) return ''; + + // var color = node.color; + // var backColor = node.backColor; + + // // if (this.options.highlightSelected && node.state.selected) { + // // if (this.options.selectedColor) { + // // color = this.options.selectedColor; + // // } + // // if (this.options.selectedBackColor) { + // // backColor = this.options.selectedBackColor; + // // } + // // } + + // if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { + // if (this.options.searchResultColor) { + // color = this.options.searchResultColor; + // } + // if (this.options.searchResultBackColor) { + // backColor = this.options.searchResultBackColor; + // } + // } + + // // return 'color:' + color + + // // ';background-color:' + backColor + ';'; + // }; // Add inline style into head Tree.prototype.injectStyle = function () { @@ -742,6 +778,20 @@ '}'; } + if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { + + var innerStyle = '' + if (this.options.selectedColor) { + innerStyle += 'color:' + this.options.selectedColor + ';'; + } + if (this.options.selectedBackColor) { + innerStyle += 'background-color:' + this.options.selectedBackColor + ';'; + } + + style += '.node-' + this.elementId + '.node-selected{' + innerStyle + '}'; + style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; + } + return this.css + style; }; @@ -862,10 +912,8 @@ */ Tree.prototype.selectNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setSelectedState(node, true, options); + this._setSelectedState(node, true, options); }, this)); - - this.render(); }; /** @@ -875,10 +923,8 @@ */ Tree.prototype.unselectNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setSelectedState(node, false, options); + this._setSelectedState(node, false, options); }, this)); - - this.render(); }; /** @@ -888,10 +934,8 @@ */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleSelectedState(node, options); + this._toggleSelectedState(node, options); }, this)); - - this.render(); }; From 4b859456e0d3499bfff325645b865ac54f720450 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 20 Jun 2015 20:59:46 +0100 Subject: [PATCH 03/52] Removed necessary option extension, already handled in forEachIdentifier --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 2 -- src/js/bootstrap-treeview.js | 2 -- tests/lib/bootstrap-treeview.js | 2 -- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 613c3dc9a..c5bcf16e5 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):d.selectable?this._toggleSelectedState(d,f.options):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c!==b.state.selected?(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this):void 0},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this._setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.state.checked?b.$el.addClass("node-checked"):b.$el.removeClass("node-checked"),b.state.disabled?b.$el.addClass("node-disabled"):b.$el.removeClass("node-disabled"),this._setSelectedState(b,b.state.selected),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                        ',node:'
                      • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):d.selectable?this._toggleSelectedState(d,f.options):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c!==b.state.selected?(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this):void 0},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this._setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.state.checked?b.$el.addClass("node-checked"):b.$el.removeClass("node-checked"),b.state.disabled?b.$el.addClass("node-disabled"):b.$el.removeClass("node-disabled"),this._setSelectedState(b,b.state.selected),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                          ',node:'
                        • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 25bfcd008..b7784016e 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -955,7 +955,6 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { - options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, false, options); this._renderNode(node); @@ -978,7 +977,6 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { - options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, true, options); if (node.nodes) { diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 25bfcd008..b7784016e 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -955,7 +955,6 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { - options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, false, options); this._renderNode(node); @@ -978,7 +977,6 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { - options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, true, options); if (node.nodes) { diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 25bfcd008..b7784016e 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -955,7 +955,6 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { - options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, false, options); this._renderNode(node); @@ -978,7 +977,6 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { - options = $.extend({}, _default.options, options); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this.setExpandedState(node, true, options); if (node.nodes) { From ea8476acf8d8495856b6e13c6b506b844ada5df0 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 21 Jun 2015 15:03:49 +0100 Subject: [PATCH 04/52] Node checked update to render checked/unchecked state via css only. #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 99 ++++++++++++++++----------------- src/js/bootstrap-treeview.js | 99 ++++++++++++++++----------------- tests/lib/bootstrap-treeview.js | 99 ++++++++++++++++----------------- 4 files changed, 148 insertions(+), 151 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index c5bcf16e5..50c152e4f 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):d.selectable?this._toggleSelectedState(d,f.options):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c!==b.state.selected?(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this):void 0},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this._setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.state.checked?b.$el.addClass("node-checked"):b.$el.removeClass("node-checked"),b.state.disabled?b.$el.addClass("node-disabled"):b.$el.removeClass("node-disabled"),this._setSelectedState(b,b.state.selected),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                            ',node:'
                          • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b)))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),this._setSelectedState(b,b.state.selected),b.state.disabled?b.$el.addClass("node-disabled"):b.$el.removeClass("node-disabled"),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                              ',node:'
                            • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index b7784016e..89bca55b3 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -331,9 +331,7 @@ } else if ((classList.indexOf('check-icon') !== -1)) { - this.toggleCheckedState(node, _default.options); - this.render(); - // TODO this._checkNode(); + this._toggleCheckedState(node, _default.options); } else { @@ -402,7 +400,7 @@ Tree.prototype._setSelectedState = function (node, state, options) { - if (state === node.state.selected) return; + // if (state === node.state.selected) return; if (state) { @@ -416,8 +414,10 @@ // Set note state node.state.selected = true; - // Add class - node.$el.addClass('node-selected'); + // Set element + if (node.$el) { + node.$el.addClass('node-selected'); + } // Optionally trigger event if (options && !options.silent) { @@ -429,8 +429,10 @@ // Set node state node.state.selected = false; - // Add class - node.$el.removeClass('node-selected'); + // Set element + if (node.$el) { + node.$el.removeClass('node-selected'); + } // Optionally trigger event if (options && !options.silent) { @@ -441,29 +443,48 @@ return this; }; - Tree.prototype.toggleCheckedState = function (node, options) { + Tree.prototype._toggleCheckedState = function (node, options) { if (!node) return; - this.setCheckedState(node, !node.state.checked, options); + this._setCheckedState(node, !node.state.checked, options); }; - Tree.prototype.setCheckedState = function (node, state, options) { + Tree.prototype._setCheckedState = function (node, state, options) { - if (state === node.state.checked) return; + // if (state === node.state.checked) return; if (state) { - // Check node + // Set node state node.state.checked = true; - if (!options.silent) { + // Set element + if (node.$el) { + node.$el.addClass('node-checked'); + node.$el.children('span.check-icon') + .removeClass(this.options.uncheckedIcon) + .addClass(this.options.checkedIcon); + } + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeChecked', $.extend(true, {}, node)); } } else { - // Uncheck node + // Set node state to unchecked node.state.checked = false; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.removeClass('node-checked'); + node.$el.children('span.check-icon') + .removeClass(this.options.checkedIcon) + .addClass(this.options.uncheckedIcon); + } + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); } } @@ -481,7 +502,7 @@ // Disable all other states this.setExpandedState(node, false, options); this._setSelectedState(node, false, options); - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); if (!options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); @@ -585,13 +606,8 @@ node.$el.empty(); } - // Set checked state - if (node.state.checked) { - node.$el.addClass('node-checked'); - } - else { - node.$el.removeClass('node-checked'); - } + // Set selected state + this._setSelectedState(node, node.state.selected); // Set disabled state if (node.state.disabled) { @@ -601,8 +617,7 @@ node.$el.removeClass('node-disabled'); } - // Set selected state - this._setSelectedState(node, node.state.selected); + // Set search result state if (node.searchResult) { @@ -663,18 +678,12 @@ // Add check / unchecked icon if (this.options.showCheckbox) { - var classList = ['check-icon']; - if (node.state.checked) { - classList.push(this.options.checkedIcon); - } - else { - classList.push(this.options.uncheckedIcon); - } - node.$el .append($(this.template.icon) - .addClass(classList.join(' ')) + .addClass('check-icon') ); + + this._setCheckedState(node, node.state.checked); } // Add text @@ -1035,10 +1044,8 @@ Tree.prototype.checkAll = function (options) { var identifiers = this.findNodes('false', 'g', 'state.checked'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, true, options); + this._setCheckedState(node, true, options); }, this)); - - this.render(); }; /** @@ -1048,10 +1055,8 @@ */ Tree.prototype.checkNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, true, options); + this._setCheckedState(node, true, options); }, this)); - - this.render(); }; /** @@ -1061,10 +1066,8 @@ Tree.prototype.uncheckAll = function (options) { var identifiers = this.findNodes('true', 'g', 'state.checked'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); }, this)); - - this.render(); }; /** @@ -1074,10 +1077,8 @@ */ Tree.prototype.uncheckNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); }, this)); - - this.render(); }; /** @@ -1087,10 +1088,8 @@ */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleCheckedState(node, options); + this._toggleCheckedState(node, options); }, this)); - - this.render(); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index b7784016e..89bca55b3 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -331,9 +331,7 @@ } else if ((classList.indexOf('check-icon') !== -1)) { - this.toggleCheckedState(node, _default.options); - this.render(); - // TODO this._checkNode(); + this._toggleCheckedState(node, _default.options); } else { @@ -402,7 +400,7 @@ Tree.prototype._setSelectedState = function (node, state, options) { - if (state === node.state.selected) return; + // if (state === node.state.selected) return; if (state) { @@ -416,8 +414,10 @@ // Set note state node.state.selected = true; - // Add class - node.$el.addClass('node-selected'); + // Set element + if (node.$el) { + node.$el.addClass('node-selected'); + } // Optionally trigger event if (options && !options.silent) { @@ -429,8 +429,10 @@ // Set node state node.state.selected = false; - // Add class - node.$el.removeClass('node-selected'); + // Set element + if (node.$el) { + node.$el.removeClass('node-selected'); + } // Optionally trigger event if (options && !options.silent) { @@ -441,29 +443,48 @@ return this; }; - Tree.prototype.toggleCheckedState = function (node, options) { + Tree.prototype._toggleCheckedState = function (node, options) { if (!node) return; - this.setCheckedState(node, !node.state.checked, options); + this._setCheckedState(node, !node.state.checked, options); }; - Tree.prototype.setCheckedState = function (node, state, options) { + Tree.prototype._setCheckedState = function (node, state, options) { - if (state === node.state.checked) return; + // if (state === node.state.checked) return; if (state) { - // Check node + // Set node state node.state.checked = true; - if (!options.silent) { + // Set element + if (node.$el) { + node.$el.addClass('node-checked'); + node.$el.children('span.check-icon') + .removeClass(this.options.uncheckedIcon) + .addClass(this.options.checkedIcon); + } + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeChecked', $.extend(true, {}, node)); } } else { - // Uncheck node + // Set node state to unchecked node.state.checked = false; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.removeClass('node-checked'); + node.$el.children('span.check-icon') + .removeClass(this.options.checkedIcon) + .addClass(this.options.uncheckedIcon); + } + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); } } @@ -481,7 +502,7 @@ // Disable all other states this.setExpandedState(node, false, options); this._setSelectedState(node, false, options); - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); if (!options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); @@ -585,13 +606,8 @@ node.$el.empty(); } - // Set checked state - if (node.state.checked) { - node.$el.addClass('node-checked'); - } - else { - node.$el.removeClass('node-checked'); - } + // Set selected state + this._setSelectedState(node, node.state.selected); // Set disabled state if (node.state.disabled) { @@ -601,8 +617,7 @@ node.$el.removeClass('node-disabled'); } - // Set selected state - this._setSelectedState(node, node.state.selected); + // Set search result state if (node.searchResult) { @@ -663,18 +678,12 @@ // Add check / unchecked icon if (this.options.showCheckbox) { - var classList = ['check-icon']; - if (node.state.checked) { - classList.push(this.options.checkedIcon); - } - else { - classList.push(this.options.uncheckedIcon); - } - node.$el .append($(this.template.icon) - .addClass(classList.join(' ')) + .addClass('check-icon') ); + + this._setCheckedState(node, node.state.checked); } // Add text @@ -1035,10 +1044,8 @@ Tree.prototype.checkAll = function (options) { var identifiers = this.findNodes('false', 'g', 'state.checked'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, true, options); + this._setCheckedState(node, true, options); }, this)); - - this.render(); }; /** @@ -1048,10 +1055,8 @@ */ Tree.prototype.checkNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, true, options); + this._setCheckedState(node, true, options); }, this)); - - this.render(); }; /** @@ -1061,10 +1066,8 @@ Tree.prototype.uncheckAll = function (options) { var identifiers = this.findNodes('true', 'g', 'state.checked'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); }, this)); - - this.render(); }; /** @@ -1074,10 +1077,8 @@ */ Tree.prototype.uncheckNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); }, this)); - - this.render(); }; /** @@ -1087,10 +1088,8 @@ */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleCheckedState(node, options); + this._toggleCheckedState(node, options); }, this)); - - this.render(); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index b7784016e..89bca55b3 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -331,9 +331,7 @@ } else if ((classList.indexOf('check-icon') !== -1)) { - this.toggleCheckedState(node, _default.options); - this.render(); - // TODO this._checkNode(); + this._toggleCheckedState(node, _default.options); } else { @@ -402,7 +400,7 @@ Tree.prototype._setSelectedState = function (node, state, options) { - if (state === node.state.selected) return; + // if (state === node.state.selected) return; if (state) { @@ -416,8 +414,10 @@ // Set note state node.state.selected = true; - // Add class - node.$el.addClass('node-selected'); + // Set element + if (node.$el) { + node.$el.addClass('node-selected'); + } // Optionally trigger event if (options && !options.silent) { @@ -429,8 +429,10 @@ // Set node state node.state.selected = false; - // Add class - node.$el.removeClass('node-selected'); + // Set element + if (node.$el) { + node.$el.removeClass('node-selected'); + } // Optionally trigger event if (options && !options.silent) { @@ -441,29 +443,48 @@ return this; }; - Tree.prototype.toggleCheckedState = function (node, options) { + Tree.prototype._toggleCheckedState = function (node, options) { if (!node) return; - this.setCheckedState(node, !node.state.checked, options); + this._setCheckedState(node, !node.state.checked, options); }; - Tree.prototype.setCheckedState = function (node, state, options) { + Tree.prototype._setCheckedState = function (node, state, options) { - if (state === node.state.checked) return; + // if (state === node.state.checked) return; if (state) { - // Check node + // Set node state node.state.checked = true; - if (!options.silent) { + // Set element + if (node.$el) { + node.$el.addClass('node-checked'); + node.$el.children('span.check-icon') + .removeClass(this.options.uncheckedIcon) + .addClass(this.options.checkedIcon); + } + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeChecked', $.extend(true, {}, node)); } } else { - // Uncheck node + // Set node state to unchecked node.state.checked = false; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.removeClass('node-checked'); + node.$el.children('span.check-icon') + .removeClass(this.options.checkedIcon) + .addClass(this.options.uncheckedIcon); + } + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); } } @@ -481,7 +502,7 @@ // Disable all other states this.setExpandedState(node, false, options); this._setSelectedState(node, false, options); - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); if (!options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); @@ -585,13 +606,8 @@ node.$el.empty(); } - // Set checked state - if (node.state.checked) { - node.$el.addClass('node-checked'); - } - else { - node.$el.removeClass('node-checked'); - } + // Set selected state + this._setSelectedState(node, node.state.selected); // Set disabled state if (node.state.disabled) { @@ -601,8 +617,7 @@ node.$el.removeClass('node-disabled'); } - // Set selected state - this._setSelectedState(node, node.state.selected); + // Set search result state if (node.searchResult) { @@ -663,18 +678,12 @@ // Add check / unchecked icon if (this.options.showCheckbox) { - var classList = ['check-icon']; - if (node.state.checked) { - classList.push(this.options.checkedIcon); - } - else { - classList.push(this.options.uncheckedIcon); - } - node.$el .append($(this.template.icon) - .addClass(classList.join(' ')) + .addClass('check-icon') ); + + this._setCheckedState(node, node.state.checked); } // Add text @@ -1035,10 +1044,8 @@ Tree.prototype.checkAll = function (options) { var identifiers = this.findNodes('false', 'g', 'state.checked'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, true, options); + this._setCheckedState(node, true, options); }, this)); - - this.render(); }; /** @@ -1048,10 +1055,8 @@ */ Tree.prototype.checkNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, true, options); + this._setCheckedState(node, true, options); }, this)); - - this.render(); }; /** @@ -1061,10 +1066,8 @@ Tree.prototype.uncheckAll = function (options) { var identifiers = this.findNodes('true', 'g', 'state.checked'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); }, this)); - - this.render(); }; /** @@ -1074,10 +1077,8 @@ */ Tree.prototype.uncheckNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setCheckedState(node, false, options); + this._setCheckedState(node, false, options); }, this)); - - this.render(); }; /** @@ -1087,10 +1088,8 @@ */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleCheckedState(node, options); + this._toggleCheckedState(node, options); }, this)); - - this.render(); }; From a5e0189f868b111def3d8557bd977deb46a3d00f Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 21 Jun 2015 18:51:28 +0100 Subject: [PATCH 05/52] Node disabled update to render state change with minimal DOM manipulation. #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 134 +++++++++++++++++--------------- src/js/bootstrap-treeview.js | 134 +++++++++++++++++--------------- tests/lib/bootstrap-treeview.js | 134 +++++++++++++++++--------------- 4 files changed, 211 insertions(+), 193 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 50c152e4f..2441bf427 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this._renderNode(d)):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):(this.toggleExpandedState(d,f.options),this._renderNode(d))}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this.setExpandedState(b,!1,d)},this))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b)))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),this._setSelectedState(b,b.state.selected),b.state.disabled?b.$el.addClass("node-disabled"):b.$el.removeClass("node-disabled"),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                ',node:'
                              • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b),this._renderNode(a)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._renderNode(a)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this.setExpandedState(d,!0,b);this._renderNode(d)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b),this._renderNode(a)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b)))},g.prototype._setDisabledState=function(b,c,d){c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b)))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),this._setSelectedState(b,b.state.selected),this._setDisabledState(b,b.state.disabled),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                  ',node:'
                                • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._setExpandedState(a,!0,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 89bca55b3..2048d4cfc 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -325,21 +325,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - - this.toggleExpandedState(node, _default.options); - this._renderNode(node); + this._toggleExpandedState(node, _default.options); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleCheckedState(node, _default.options); } else { - if (node.selectable) { this._toggleSelectedState(node, _default.options); } else { - this.toggleExpandedState(node, _default.options); - this._renderNode(node); + this._toggleExpandedState(node, _default.options); } } }; @@ -357,38 +352,62 @@ return node; }; - Tree.prototype.toggleExpandedState = function (node, options) { + Tree.prototype._toggleExpandedState = function (node, options) { if (!node) return; - this.setExpandedState(node, !node.state.expanded, options); + this._setExpandedState(node, !node.state.expanded, options); }; - Tree.prototype.setExpandedState = function (node, state, options) { + Tree.prototype._setExpandedState = function (node, state, options) { - if (state === node.state.expanded) return; + // if (state === node.state.expanded) return; if (state && node.nodes) { - // Expand a node + // Set node state node.state.expanded = true; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.children('span.expand-icon') + .removeClass(this.options.expandIcon) + .addClass(this.options.collapseIcon); + } + + // Render child nodes + this._expandNode(node); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); } } else if (!state) { - // Collapse a node + // Set node state node.state.expanded = false; - if (!options.silent) { - this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + + // Set element + if (node.$el) { + node.$el.children('span.expand-icon') + .removeClass(this.options.collapseIcon) + .addClass(this.options.expandIcon); } - // Collapse child nodes - if (node.nodes && !options.ignoreChildren) { + // Collapse children + if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { console.log('recurse children') - this.setExpandedState(node, false, options); + this._setExpandedState(node, false, options); }, this)); } + + // Remove child nodes + this._collapseNode(node); + + // Optionally trigger event + if (options && !options.silent) { + this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + } } }; @@ -450,6 +469,7 @@ Tree.prototype._setCheckedState = function (node, state, options) { + // TODO Doesn't work during initialize / first render // if (state === node.state.checked) return; if (state) { @@ -490,29 +510,40 @@ } }; - Tree.prototype.setDisabledState = function (node, state, options) { + Tree.prototype._setDisabledState = function (node, state, options) { - if (state === node.state.disabled) return; + // if (state === node.state.disabled) return; if (state) { - // Disable node + // Set node state to disabled node.state.disabled = true; // Disable all other states - this.setExpandedState(node, false, options); this._setSelectedState(node, false, options); this._setCheckedState(node, false, options); + this._setExpandedState(node, false, options); + + // Set element + if (node.$el) { + node.$el.addClass('node-disabled'); + } - if (!options.silent) { + if (options && !options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); } } else { - // Enabled node + // Set node state to enabled node.state.disabled = false; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.removeClass('node-disabled'); + } + + if (options && !options.silent) { this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); } } @@ -610,12 +641,7 @@ this._setSelectedState(node, node.state.selected); // Set disabled state - if (node.state.disabled) { - node.$el.addClass('node-disabled'); - } - else { - node.$el.removeClass('node-disabled'); - } + this._setDisabledState(node, node.state.disabled); @@ -640,12 +666,6 @@ var classList = []; if (node.nodes) { classList.push('expand-icon'); - if (node.state.expanded) { - classList.push(this.options.collapseIcon); - } - else { - classList.push(this.options.expandIcon); - } } else { classList.push(this.options.emptyIcon); @@ -656,6 +676,8 @@ .addClass(classList.join(' ')) ); + this._setExpandedState(node, node.state.expanded); + // Add node icon if (this.options.showIcon) { @@ -965,8 +987,7 @@ */ Tree.prototype.collapseNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, false, options); - this._renderNode(node); + this._setExpandedState(node, false, options); }, this)); }; @@ -987,18 +1008,17 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } - this._renderNode(node); + this._setExpandedState(node, true, options); }, this)); }; Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { console.log('test - ' + node.text); - this.setExpandedState(node, (level > 0) ? true : false, options); + this._setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); } @@ -1016,9 +1036,8 @@ var tmpNode; while (tmpNode = this.getParent(parentNode)) { parentNode = tmpNode; - this.setExpandedState(parentNode, true, options); + this._setExpandedState(parentNode, true, options); }; - this._renderNode(parentNode); }, this)); }; @@ -1029,11 +1048,8 @@ */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleExpandedState(node, options); - this._renderNode(node); + this._toggleExpandedState(node, options); }, this)); - - // this.render(); }; @@ -1100,10 +1116,8 @@ Tree.prototype.disableAll = function (options) { var identifiers = this.findNodes('false', 'g', 'state.disabled'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, true, options); + this._setDisabledState(node, true, options); }, this)); - - this.render(); }; /** @@ -1113,10 +1127,8 @@ */ Tree.prototype.disableNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, true, options); + this._setDisabledState(node, true, options); }, this)); - - this.render(); }; /** @@ -1126,10 +1138,8 @@ Tree.prototype.enableAll = function (options) { var identifiers = this.findNodes('true', 'g', 'state.disabled'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, false, options); + this._setDisabledState(node, false, options); }, this)); - - this.render(); }; /** @@ -1139,10 +1149,8 @@ */ Tree.prototype.enableNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, false, options); + this._setDisabledState(node, false, options); }, this)); - - this.render(); }; /** @@ -1152,10 +1160,8 @@ */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, !node.state.disabled, options); + this._setDisabledState(node, !node.state.disabled, options); }, this)); - - this.render(); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 89bca55b3..2048d4cfc 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -325,21 +325,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - - this.toggleExpandedState(node, _default.options); - this._renderNode(node); + this._toggleExpandedState(node, _default.options); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleCheckedState(node, _default.options); } else { - if (node.selectable) { this._toggleSelectedState(node, _default.options); } else { - this.toggleExpandedState(node, _default.options); - this._renderNode(node); + this._toggleExpandedState(node, _default.options); } } }; @@ -357,38 +352,62 @@ return node; }; - Tree.prototype.toggleExpandedState = function (node, options) { + Tree.prototype._toggleExpandedState = function (node, options) { if (!node) return; - this.setExpandedState(node, !node.state.expanded, options); + this._setExpandedState(node, !node.state.expanded, options); }; - Tree.prototype.setExpandedState = function (node, state, options) { + Tree.prototype._setExpandedState = function (node, state, options) { - if (state === node.state.expanded) return; + // if (state === node.state.expanded) return; if (state && node.nodes) { - // Expand a node + // Set node state node.state.expanded = true; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.children('span.expand-icon') + .removeClass(this.options.expandIcon) + .addClass(this.options.collapseIcon); + } + + // Render child nodes + this._expandNode(node); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); } } else if (!state) { - // Collapse a node + // Set node state node.state.expanded = false; - if (!options.silent) { - this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + + // Set element + if (node.$el) { + node.$el.children('span.expand-icon') + .removeClass(this.options.collapseIcon) + .addClass(this.options.expandIcon); } - // Collapse child nodes - if (node.nodes && !options.ignoreChildren) { + // Collapse children + if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { console.log('recurse children') - this.setExpandedState(node, false, options); + this._setExpandedState(node, false, options); }, this)); } + + // Remove child nodes + this._collapseNode(node); + + // Optionally trigger event + if (options && !options.silent) { + this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + } } }; @@ -450,6 +469,7 @@ Tree.prototype._setCheckedState = function (node, state, options) { + // TODO Doesn't work during initialize / first render // if (state === node.state.checked) return; if (state) { @@ -490,29 +510,40 @@ } }; - Tree.prototype.setDisabledState = function (node, state, options) { + Tree.prototype._setDisabledState = function (node, state, options) { - if (state === node.state.disabled) return; + // if (state === node.state.disabled) return; if (state) { - // Disable node + // Set node state to disabled node.state.disabled = true; // Disable all other states - this.setExpandedState(node, false, options); this._setSelectedState(node, false, options); this._setCheckedState(node, false, options); + this._setExpandedState(node, false, options); + + // Set element + if (node.$el) { + node.$el.addClass('node-disabled'); + } - if (!options.silent) { + if (options && !options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); } } else { - // Enabled node + // Set node state to enabled node.state.disabled = false; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.removeClass('node-disabled'); + } + + if (options && !options.silent) { this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); } } @@ -610,12 +641,7 @@ this._setSelectedState(node, node.state.selected); // Set disabled state - if (node.state.disabled) { - node.$el.addClass('node-disabled'); - } - else { - node.$el.removeClass('node-disabled'); - } + this._setDisabledState(node, node.state.disabled); @@ -640,12 +666,6 @@ var classList = []; if (node.nodes) { classList.push('expand-icon'); - if (node.state.expanded) { - classList.push(this.options.collapseIcon); - } - else { - classList.push(this.options.expandIcon); - } } else { classList.push(this.options.emptyIcon); @@ -656,6 +676,8 @@ .addClass(classList.join(' ')) ); + this._setExpandedState(node, node.state.expanded); + // Add node icon if (this.options.showIcon) { @@ -965,8 +987,7 @@ */ Tree.prototype.collapseNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, false, options); - this._renderNode(node); + this._setExpandedState(node, false, options); }, this)); }; @@ -987,18 +1008,17 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } - this._renderNode(node); + this._setExpandedState(node, true, options); }, this)); }; Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { console.log('test - ' + node.text); - this.setExpandedState(node, (level > 0) ? true : false, options); + this._setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); } @@ -1016,9 +1036,8 @@ var tmpNode; while (tmpNode = this.getParent(parentNode)) { parentNode = tmpNode; - this.setExpandedState(parentNode, true, options); + this._setExpandedState(parentNode, true, options); }; - this._renderNode(parentNode); }, this)); }; @@ -1029,11 +1048,8 @@ */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleExpandedState(node, options); - this._renderNode(node); + this._toggleExpandedState(node, options); }, this)); - - // this.render(); }; @@ -1100,10 +1116,8 @@ Tree.prototype.disableAll = function (options) { var identifiers = this.findNodes('false', 'g', 'state.disabled'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, true, options); + this._setDisabledState(node, true, options); }, this)); - - this.render(); }; /** @@ -1113,10 +1127,8 @@ */ Tree.prototype.disableNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, true, options); + this._setDisabledState(node, true, options); }, this)); - - this.render(); }; /** @@ -1126,10 +1138,8 @@ Tree.prototype.enableAll = function (options) { var identifiers = this.findNodes('true', 'g', 'state.disabled'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, false, options); + this._setDisabledState(node, false, options); }, this)); - - this.render(); }; /** @@ -1139,10 +1149,8 @@ */ Tree.prototype.enableNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, false, options); + this._setDisabledState(node, false, options); }, this)); - - this.render(); }; /** @@ -1152,10 +1160,8 @@ */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, !node.state.disabled, options); + this._setDisabledState(node, !node.state.disabled, options); }, this)); - - this.render(); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 89bca55b3..2048d4cfc 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -325,21 +325,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - - this.toggleExpandedState(node, _default.options); - this._renderNode(node); + this._toggleExpandedState(node, _default.options); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleCheckedState(node, _default.options); } else { - if (node.selectable) { this._toggleSelectedState(node, _default.options); } else { - this.toggleExpandedState(node, _default.options); - this._renderNode(node); + this._toggleExpandedState(node, _default.options); } } }; @@ -357,38 +352,62 @@ return node; }; - Tree.prototype.toggleExpandedState = function (node, options) { + Tree.prototype._toggleExpandedState = function (node, options) { if (!node) return; - this.setExpandedState(node, !node.state.expanded, options); + this._setExpandedState(node, !node.state.expanded, options); }; - Tree.prototype.setExpandedState = function (node, state, options) { + Tree.prototype._setExpandedState = function (node, state, options) { - if (state === node.state.expanded) return; + // if (state === node.state.expanded) return; if (state && node.nodes) { - // Expand a node + // Set node state node.state.expanded = true; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.children('span.expand-icon') + .removeClass(this.options.expandIcon) + .addClass(this.options.collapseIcon); + } + + // Render child nodes + this._expandNode(node); + + // Optionally trigger event + if (options && !options.silent) { this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); } } else if (!state) { - // Collapse a node + // Set node state node.state.expanded = false; - if (!options.silent) { - this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + + // Set element + if (node.$el) { + node.$el.children('span.expand-icon') + .removeClass(this.options.collapseIcon) + .addClass(this.options.expandIcon); } - // Collapse child nodes - if (node.nodes && !options.ignoreChildren) { + // Collapse children + if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { console.log('recurse children') - this.setExpandedState(node, false, options); + this._setExpandedState(node, false, options); }, this)); } + + // Remove child nodes + this._collapseNode(node); + + // Optionally trigger event + if (options && !options.silent) { + this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + } } }; @@ -450,6 +469,7 @@ Tree.prototype._setCheckedState = function (node, state, options) { + // TODO Doesn't work during initialize / first render // if (state === node.state.checked) return; if (state) { @@ -490,29 +510,40 @@ } }; - Tree.prototype.setDisabledState = function (node, state, options) { + Tree.prototype._setDisabledState = function (node, state, options) { - if (state === node.state.disabled) return; + // if (state === node.state.disabled) return; if (state) { - // Disable node + // Set node state to disabled node.state.disabled = true; // Disable all other states - this.setExpandedState(node, false, options); this._setSelectedState(node, false, options); this._setCheckedState(node, false, options); + this._setExpandedState(node, false, options); + + // Set element + if (node.$el) { + node.$el.addClass('node-disabled'); + } - if (!options.silent) { + if (options && !options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); } } else { - // Enabled node + // Set node state to enabled node.state.disabled = false; - if (!options.silent) { + + // Set element + if (node.$el) { + node.$el.removeClass('node-disabled'); + } + + if (options && !options.silent) { this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); } } @@ -610,12 +641,7 @@ this._setSelectedState(node, node.state.selected); // Set disabled state - if (node.state.disabled) { - node.$el.addClass('node-disabled'); - } - else { - node.$el.removeClass('node-disabled'); - } + this._setDisabledState(node, node.state.disabled); @@ -640,12 +666,6 @@ var classList = []; if (node.nodes) { classList.push('expand-icon'); - if (node.state.expanded) { - classList.push(this.options.collapseIcon); - } - else { - classList.push(this.options.expandIcon); - } } else { classList.push(this.options.emptyIcon); @@ -656,6 +676,8 @@ .addClass(classList.join(' ')) ); + this._setExpandedState(node, node.state.expanded); + // Add node icon if (this.options.showIcon) { @@ -965,8 +987,7 @@ */ Tree.prototype.collapseNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, false, options); - this._renderNode(node); + this._setExpandedState(node, false, options); }, this)); }; @@ -987,18 +1008,17 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } - this._renderNode(node); + this._setExpandedState(node, true, options); }, this)); }; Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { console.log('test - ' + node.text); - this.setExpandedState(node, (level > 0) ? true : false, options); + this._setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); } @@ -1016,9 +1036,8 @@ var tmpNode; while (tmpNode = this.getParent(parentNode)) { parentNode = tmpNode; - this.setExpandedState(parentNode, true, options); + this._setExpandedState(parentNode, true, options); }; - this._renderNode(parentNode); }, this)); }; @@ -1029,11 +1048,8 @@ */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.toggleExpandedState(node, options); - this._renderNode(node); + this._toggleExpandedState(node, options); }, this)); - - // this.render(); }; @@ -1100,10 +1116,8 @@ Tree.prototype.disableAll = function (options) { var identifiers = this.findNodes('false', 'g', 'state.disabled'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, true, options); + this._setDisabledState(node, true, options); }, this)); - - this.render(); }; /** @@ -1113,10 +1127,8 @@ */ Tree.prototype.disableNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, true, options); + this._setDisabledState(node, true, options); }, this)); - - this.render(); }; /** @@ -1126,10 +1138,8 @@ Tree.prototype.enableAll = function (options) { var identifiers = this.findNodes('true', 'g', 'state.disabled'); this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, false, options); + this._setDisabledState(node, false, options); }, this)); - - this.render(); }; /** @@ -1139,10 +1149,8 @@ */ Tree.prototype.enableNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, false, options); + this._setDisabledState(node, false, options); }, this)); - - this.render(); }; /** @@ -1152,10 +1160,8 @@ */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this.setDisabledState(node, !node.state.disabled, options); + this._setDisabledState(node, !node.state.disabled, options); }, this)); - - this.render(); }; From 8927f9d1f80228e1fbad232769fa34ba9d0875a6 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 21 Jun 2015 19:44:47 +0100 Subject: [PATCH 06/52] Fixed bug with initial states not being set, due to there being no change in state #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 56 ++++++++++++++++----------------- src/js/bootstrap-treeview.js | 56 ++++++++++++++++----------------- tests/lib/bootstrap-treeview.js | 56 ++++++++++++++++----------------- 4 files changed, 85 insertions(+), 85 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 2441bf427..e87f79545 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b)))},g.prototype._setDisabledState=function(b,c,d){c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b)))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert"),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),this._setSelectedState(b,b.state.selected),this._setDisabledState(b,b.state.disabled),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                    ',node:'
                                  • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){a.nodes&&this._expandLevels(a.nodes,b.levels-1,b),this._setExpandedState(a,!0,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                      ',node:'
                                    • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 2048d4cfc..c916dee2e 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -359,7 +359,9 @@ Tree.prototype._setExpandedState = function (node, state, options) { - // if (state === node.state.expanded) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.expanded) return; if (state && node.nodes) { @@ -419,7 +421,9 @@ Tree.prototype._setSelectedState = function (node, state, options) { - // if (state === node.state.selected) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.selected) return; if (state) { @@ -469,8 +473,9 @@ Tree.prototype._setCheckedState = function (node, state, options) { - // TODO Doesn't work during initialize / first render - // if (state === node.state.checked) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.checked) return; if (state) { @@ -512,7 +517,9 @@ Tree.prototype._setDisabledState = function (node, state, options) { - // if (state === node.state.disabled) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.disabled) return; if (state) { @@ -529,6 +536,7 @@ node.$el.addClass('node-disabled'); } + // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); } @@ -543,6 +551,7 @@ node.$el.removeClass('node-disabled'); } + // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); } @@ -581,7 +590,7 @@ var $el = $(this.template.node); if (pEl) { - console.log('insert'); + console.log('insert - ' + pEl.text()); this.$wrapper.children().eq(pEl.index()).after($el); } else { @@ -596,7 +605,7 @@ if (!node.nodes) return; console.log('collapseNode - ' + node.text); - $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { + $.each(node.nodes, $.proxy(function (index, node) { this._collapseNode(node); if (node.$el) { node.$el.remove(); @@ -610,7 +619,8 @@ console.log('expandNode - ' + node.text); var $pEl = node.$el; - $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { + $.each(node.nodes/*.slice(0).reverse()*/, $.proxy(function (index, childNode) { + console.log('expandNode child ' + node.text + ' > ' + childNode.text); childNode.level = node.level + 1; this._renderNode(childNode, $pEl); $pEl = childNode.$el; @@ -637,12 +647,6 @@ node.$el.empty(); } - // Set selected state - this._setSelectedState(node, node.state.selected); - - // Set disabled state - this._setDisabledState(node, node.state.disabled); - // Set search result state @@ -676,8 +680,6 @@ .addClass(classList.join(' ')) ); - this._setExpandedState(node, node.state.expanded); - // Add node icon if (this.options.showIcon) { @@ -704,13 +706,10 @@ .append($(this.template.icon) .addClass('check-icon') ); - - this._setCheckedState(node, node.state.checked); } // Add text if (this.options.enableLinks) { - // Add hyperlink node.$el .append($(this.template.link) .attr('href', node.href) @@ -718,7 +717,6 @@ ); } else { - // otherwise just text node.$el .append(node.text); } @@ -733,13 +731,15 @@ }, this)); } - // Recursively add child ndoes - if (node.nodes && node.state.expanded && !node.state.disabled) { - this._expandNode(node); - } - else { - this._collapseNode(node); - } + // Set various node states + this._setSelectedState(node, node.state.selected); + this._setCheckedState(node, node.state.checked); + + // Set expanded state also triggers recursive tree build + this._setExpandedState(node, node.state.expanded); + + // Finally disabled, which will override any of previous states when true + this._setDisabledState(node, node.state.disabled); }; // Define any node level style override for @@ -1008,10 +1008,10 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } - this._setExpandedState(node, true, options); }, this)); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 2048d4cfc..c916dee2e 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -359,7 +359,9 @@ Tree.prototype._setExpandedState = function (node, state, options) { - // if (state === node.state.expanded) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.expanded) return; if (state && node.nodes) { @@ -419,7 +421,9 @@ Tree.prototype._setSelectedState = function (node, state, options) { - // if (state === node.state.selected) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.selected) return; if (state) { @@ -469,8 +473,9 @@ Tree.prototype._setCheckedState = function (node, state, options) { - // TODO Doesn't work during initialize / first render - // if (state === node.state.checked) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.checked) return; if (state) { @@ -512,7 +517,9 @@ Tree.prototype._setDisabledState = function (node, state, options) { - // if (state === node.state.disabled) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.disabled) return; if (state) { @@ -529,6 +536,7 @@ node.$el.addClass('node-disabled'); } + // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); } @@ -543,6 +551,7 @@ node.$el.removeClass('node-disabled'); } + // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); } @@ -581,7 +590,7 @@ var $el = $(this.template.node); if (pEl) { - console.log('insert'); + console.log('insert - ' + pEl.text()); this.$wrapper.children().eq(pEl.index()).after($el); } else { @@ -596,7 +605,7 @@ if (!node.nodes) return; console.log('collapseNode - ' + node.text); - $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { + $.each(node.nodes, $.proxy(function (index, node) { this._collapseNode(node); if (node.$el) { node.$el.remove(); @@ -610,7 +619,8 @@ console.log('expandNode - ' + node.text); var $pEl = node.$el; - $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { + $.each(node.nodes/*.slice(0).reverse()*/, $.proxy(function (index, childNode) { + console.log('expandNode child ' + node.text + ' > ' + childNode.text); childNode.level = node.level + 1; this._renderNode(childNode, $pEl); $pEl = childNode.$el; @@ -637,12 +647,6 @@ node.$el.empty(); } - // Set selected state - this._setSelectedState(node, node.state.selected); - - // Set disabled state - this._setDisabledState(node, node.state.disabled); - // Set search result state @@ -676,8 +680,6 @@ .addClass(classList.join(' ')) ); - this._setExpandedState(node, node.state.expanded); - // Add node icon if (this.options.showIcon) { @@ -704,13 +706,10 @@ .append($(this.template.icon) .addClass('check-icon') ); - - this._setCheckedState(node, node.state.checked); } // Add text if (this.options.enableLinks) { - // Add hyperlink node.$el .append($(this.template.link) .attr('href', node.href) @@ -718,7 +717,6 @@ ); } else { - // otherwise just text node.$el .append(node.text); } @@ -733,13 +731,15 @@ }, this)); } - // Recursively add child ndoes - if (node.nodes && node.state.expanded && !node.state.disabled) { - this._expandNode(node); - } - else { - this._collapseNode(node); - } + // Set various node states + this._setSelectedState(node, node.state.selected); + this._setCheckedState(node, node.state.checked); + + // Set expanded state also triggers recursive tree build + this._setExpandedState(node, node.state.expanded); + + // Finally disabled, which will override any of previous states when true + this._setDisabledState(node, node.state.disabled); }; // Define any node level style override for @@ -1008,10 +1008,10 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } - this._setExpandedState(node, true, options); }, this)); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 2048d4cfc..c916dee2e 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -359,7 +359,9 @@ Tree.prototype._setExpandedState = function (node, state, options) { - // if (state === node.state.expanded) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.expanded) return; if (state && node.nodes) { @@ -419,7 +421,9 @@ Tree.prototype._setSelectedState = function (node, state, options) { - // if (state === node.state.selected) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.selected) return; if (state) { @@ -469,8 +473,9 @@ Tree.prototype._setCheckedState = function (node, state, options) { - // TODO Doesn't work during initialize / first render - // if (state === node.state.checked) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.checked) return; if (state) { @@ -512,7 +517,9 @@ Tree.prototype._setDisabledState = function (node, state, options) { - // if (state === node.state.disabled) return; + // We never pass options when rendering, so the only time + // we need to validate state is from user interaction + if (options && state === node.state.disabled) return; if (state) { @@ -529,6 +536,7 @@ node.$el.addClass('node-disabled'); } + // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); } @@ -543,6 +551,7 @@ node.$el.removeClass('node-disabled'); } + // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); } @@ -581,7 +590,7 @@ var $el = $(this.template.node); if (pEl) { - console.log('insert'); + console.log('insert - ' + pEl.text()); this.$wrapper.children().eq(pEl.index()).after($el); } else { @@ -596,7 +605,7 @@ if (!node.nodes) return; console.log('collapseNode - ' + node.text); - $.each(node.nodes, $.proxy(function _collapseChildNodes(index, node) { + $.each(node.nodes, $.proxy(function (index, node) { this._collapseNode(node); if (node.$el) { node.$el.remove(); @@ -610,7 +619,8 @@ console.log('expandNode - ' + node.text); var $pEl = node.$el; - $.each(node.nodes, $.proxy(function _addChildNodes(index, childNode) { + $.each(node.nodes/*.slice(0).reverse()*/, $.proxy(function (index, childNode) { + console.log('expandNode child ' + node.text + ' > ' + childNode.text); childNode.level = node.level + 1; this._renderNode(childNode, $pEl); $pEl = childNode.$el; @@ -637,12 +647,6 @@ node.$el.empty(); } - // Set selected state - this._setSelectedState(node, node.state.selected); - - // Set disabled state - this._setDisabledState(node, node.state.disabled); - // Set search result state @@ -676,8 +680,6 @@ .addClass(classList.join(' ')) ); - this._setExpandedState(node, node.state.expanded); - // Add node icon if (this.options.showIcon) { @@ -704,13 +706,10 @@ .append($(this.template.icon) .addClass('check-icon') ); - - this._setCheckedState(node, node.state.checked); } // Add text if (this.options.enableLinks) { - // Add hyperlink node.$el .append($(this.template.link) .attr('href', node.href) @@ -718,7 +717,6 @@ ); } else { - // otherwise just text node.$el .append(node.text); } @@ -733,13 +731,15 @@ }, this)); } - // Recursively add child ndoes - if (node.nodes && node.state.expanded && !node.state.disabled) { - this._expandNode(node); - } - else { - this._collapseNode(node); - } + // Set various node states + this._setSelectedState(node, node.state.selected); + this._setCheckedState(node, node.state.checked); + + // Set expanded state also triggers recursive tree build + this._setExpandedState(node, node.state.expanded); + + // Finally disabled, which will override any of previous states when true + this._setDisabledState(node, node.state.disabled); }; // Define any node level style override for @@ -1008,10 +1008,10 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } - this._setExpandedState(node, true, options); }, this)); }; From c9486069fcbaf9510121456d8da331cd53829644 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Fri, 26 Jun 2015 18:11:02 +0100 Subject: [PATCH 07/52] Fixes child rendering issues #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 4 ++-- src/js/bootstrap-treeview.js | 4 ++-- tests/lib/bootstrap-treeview.js | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index e87f79545..64a274235 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes,a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c),c=d.$el},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                        ',node:'
                                      • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                          ',node:'
                                        • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index c916dee2e..4048df89b 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -619,11 +619,11 @@ console.log('expandNode - ' + node.text); var $pEl = node.$el; - $.each(node.nodes/*.slice(0).reverse()*/, $.proxy(function (index, childNode) { + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { console.log('expandNode child ' + node.text + ' > ' + childNode.text); childNode.level = node.level + 1; this._renderNode(childNode, $pEl); - $pEl = childNode.$el; + // $pEl = childNode.$el; }, this)); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index c916dee2e..4048df89b 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -619,11 +619,11 @@ console.log('expandNode - ' + node.text); var $pEl = node.$el; - $.each(node.nodes/*.slice(0).reverse()*/, $.proxy(function (index, childNode) { + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { console.log('expandNode child ' + node.text + ' > ' + childNode.text); childNode.level = node.level + 1; this._renderNode(childNode, $pEl); - $pEl = childNode.$el; + // $pEl = childNode.$el; }, this)); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index c916dee2e..4048df89b 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -619,11 +619,11 @@ console.log('expandNode - ' + node.text); var $pEl = node.$el; - $.each(node.nodes/*.slice(0).reverse()*/, $.proxy(function (index, childNode) { + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { console.log('expandNode child ' + node.text + ' > ' + childNode.text); childNode.level = node.level + 1; this._renderNode(childNode, $pEl); - $pEl = childNode.$el; + // $pEl = childNode.$el; }, this)); }; From b9564a2e8d6c20bf9baedb5166acd061a172aa4c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Fri, 26 Jun 2015 18:28:58 +0100 Subject: [PATCH 08/52] Implemented selectedIcon as part of setSelectedState #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 28 +++++++++++++++------------- src/js/bootstrap-treeview.js | 28 +++++++++++++++------------- tests/lib/bootstrap-treeview.js | 28 +++++++++++++++------------- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 64a274235..e8318a769 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&b.$el.addClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&b.$el.removeClass("node-selected"),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                            ',node:'
                                          • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this.options.nodeIcon).addClass(b.selectedIcon||this.options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this.options.selectedIcon).addClass(b.icon||this.options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                              ',node:'
                                            • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 4048df89b..8e1b82a7c 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -440,6 +440,12 @@ // Set element if (node.$el) { node.$el.addClass('node-selected'); + + if (node.selectedIcon || this.options.selectedIcon) { + node.$el.children('span.node-icon') + .removeClass(node.icon || this.options.nodeIcon) + .addClass(node.selectedIcon || this.options.selectedIcon); + } } // Optionally trigger event @@ -455,6 +461,12 @@ // Set element if (node.$el) { node.$el.removeClass('node-selected'); + + if (node.selectedIcon || this.options.selectedIcon) { + node.$el.children('span.node-icon') + .removeClass(node.selectedIcon || this.options.selectedIcon) + .addClass(node.icon || this.options.nodeIcon); + } } // Optionally trigger event @@ -683,25 +695,15 @@ // Add node icon if (this.options.showIcon) { - - var classList = ['node-icon']; - - classList.push(node.icon || this.options.nodeIcon); - if (node.state.selected) { - classList.pop(); - classList.push(node.selectedIcon || this.options.selectedIcon || - node.icon || this.options.nodeIcon); - } - node.$el .append($(this.template.icon) - .addClass(classList.join(' ')) + .addClass('node-icon') + .addClass(node.icon || this.options.nodeIcon) ); } - // Add check / unchecked icon + // Add checkable icon if (this.options.showCheckbox) { - node.$el .append($(this.template.icon) .addClass('check-icon') diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 4048df89b..8e1b82a7c 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -440,6 +440,12 @@ // Set element if (node.$el) { node.$el.addClass('node-selected'); + + if (node.selectedIcon || this.options.selectedIcon) { + node.$el.children('span.node-icon') + .removeClass(node.icon || this.options.nodeIcon) + .addClass(node.selectedIcon || this.options.selectedIcon); + } } // Optionally trigger event @@ -455,6 +461,12 @@ // Set element if (node.$el) { node.$el.removeClass('node-selected'); + + if (node.selectedIcon || this.options.selectedIcon) { + node.$el.children('span.node-icon') + .removeClass(node.selectedIcon || this.options.selectedIcon) + .addClass(node.icon || this.options.nodeIcon); + } } // Optionally trigger event @@ -683,25 +695,15 @@ // Add node icon if (this.options.showIcon) { - - var classList = ['node-icon']; - - classList.push(node.icon || this.options.nodeIcon); - if (node.state.selected) { - classList.pop(); - classList.push(node.selectedIcon || this.options.selectedIcon || - node.icon || this.options.nodeIcon); - } - node.$el .append($(this.template.icon) - .addClass(classList.join(' ')) + .addClass('node-icon') + .addClass(node.icon || this.options.nodeIcon) ); } - // Add check / unchecked icon + // Add checkable icon if (this.options.showCheckbox) { - node.$el .append($(this.template.icon) .addClass('check-icon') diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 4048df89b..8e1b82a7c 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -440,6 +440,12 @@ // Set element if (node.$el) { node.$el.addClass('node-selected'); + + if (node.selectedIcon || this.options.selectedIcon) { + node.$el.children('span.node-icon') + .removeClass(node.icon || this.options.nodeIcon) + .addClass(node.selectedIcon || this.options.selectedIcon); + } } // Optionally trigger event @@ -455,6 +461,12 @@ // Set element if (node.$el) { node.$el.removeClass('node-selected'); + + if (node.selectedIcon || this.options.selectedIcon) { + node.$el.children('span.node-icon') + .removeClass(node.selectedIcon || this.options.selectedIcon) + .addClass(node.icon || this.options.nodeIcon); + } } // Optionally trigger event @@ -683,25 +695,15 @@ // Add node icon if (this.options.showIcon) { - - var classList = ['node-icon']; - - classList.push(node.icon || this.options.nodeIcon); - if (node.state.selected) { - classList.pop(); - classList.push(node.selectedIcon || this.options.selectedIcon || - node.icon || this.options.nodeIcon); - } - node.$el .append($(this.template.icon) - .addClass(classList.join(' ')) + .addClass('node-icon') + .addClass(node.icon || this.options.nodeIcon) ); } - // Add check / unchecked icon + // Add checkable icon if (this.options.showCheckbox) { - node.$el .append($(this.template.icon) .addClass('check-icon') From 71a0559142c64529006abc4c7488a768f89d1dd6 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Fri, 26 Jun 2015 19:00:55 +0100 Subject: [PATCH 09/52] Implemented search results using css only, without the need to render. --- dist/bootstrap-treeview.min.css | 2 +- dist/bootstrap-treeview.min.js | 2 +- public/css/bootstrap-treeview.css | 9 -------- public/js/bootstrap-treeview.js | 37 +++++++++++++++---------------- src/css/bootstrap-treeview.css | 9 -------- src/js/bootstrap-treeview.js | 37 +++++++++++++++---------------- tests/lib/bootstrap-treeview.css | 9 -------- tests/lib/bootstrap-treeview.js | 37 +++++++++++++++---------------- tests/tests.js | 4 ++-- 9 files changed, 58 insertions(+), 88 deletions(-) diff --git a/dist/bootstrap-treeview.min.css b/dist/bootstrap-treeview.min.css index ca804945b..57a348a87 100644 --- a/dist/bootstrap-treeview.min.css +++ b/dist/bootstrap-treeview.min.css @@ -1 +1 @@ -.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}.treeview .node-selected{background-color:#428bca!important;color:#FFF!important} \ No newline at end of file +.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed} \ No newline at end of file diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index e8318a769..280366f35 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this.options.nodeIcon).addClass(b.selectedIcon||this.options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this.options.selectedIcon).addClass(b.icon||this.options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId)),b.searchResult?b.$el.addClass("node-result"):b.$el.removeClass("node-result");for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                                ',node:'
                                              • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this.options.nodeIcon).addClass(b.selectedIcon||this.options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this.options.selectedIcon).addClass(b.icon||this.options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSearchResults&&(this.options.searchResultColor||this.options.searchResultBackColor)){var b="";this.options.searchResultColor&&(b+="color:"+this.options.searchResultColor+";"),this.options.searchResultBackColor&&(b+="background-color:"+this.options.searchResultBackColor+";"),a+=".node-"+this.elementId+".node-result{"+b+"}",a+=".node-"+this.elementId+".node-result:hover{"+b+"}"}if(this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                                  ',node:'
                                                • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/css/bootstrap-treeview.css b/public/css/bootstrap-treeview.css index d62bf7c7b..62ea91fc1 100644 --- a/public/css/bootstrap-treeview.css +++ b/public/css/bootstrap-treeview.css @@ -35,12 +35,3 @@ color: silver; cursor: not-allowed; } - -/* - Only valid when either options selectedColor or - selectedBackColor are left undefined -*/ -.treeview .node-selected { - background-color: #428bca !important; - color: #FFFFFF !important; -} \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 8e1b82a7c..645601f7e 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -440,7 +440,7 @@ // Set element if (node.$el) { node.$el.addClass('node-selected'); - + if (node.selectedIcon || this.options.selectedIcon) { node.$el.children('span.node-icon') .removeClass(node.icon || this.options.nodeIcon) @@ -659,16 +659,6 @@ node.$el.empty(); } - - - // Set search result state - if (node.searchResult) { - node.$el.addClass('node-result'); - } - else { - node.$el.removeClass('node-result'); - } - // Set state based style overrides // node.$el.attr('style', this.buildStyleOverride(node)); @@ -811,6 +801,20 @@ '}'; } + if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { + + var innerStyle = '' + if (this.options.searchResultColor) { + innerStyle += 'color:' + this.options.searchResultColor + ';'; + } + if (this.options.searchResultBackColor) { + innerStyle += 'background-color:' + this.options.searchResultBackColor + ';'; + } + + style += '.node-' + this.elementId + '.node-result{' + innerStyle + '}'; + style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; + } + if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { var innerStyle = '' @@ -1201,7 +1205,7 @@ Tree.prototype.search = function (pattern, options) { options = $.extend({}, _default.searchOptions, options); - this.clearSearch({ render: false }); + this.clearSearch(); var results = []; if (pattern && pattern.length > 0) { @@ -1222,6 +1226,7 @@ // and when identifying result to be cleared $.each(results, function (index, node) { node.searchResult = true; + node.$el.addClass('node-result'); }) } @@ -1230,9 +1235,6 @@ if (options.revealResults) { this.revealNode(results); } - else { - this.render(); - } this.$element.trigger('searchComplete', $.extend(true, {}, results)); @@ -1248,11 +1250,8 @@ var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { node.searchResult = false; + node.$el.removeClass('node-result'); }); - - if (options.render) { - this.render(); - } this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; diff --git a/src/css/bootstrap-treeview.css b/src/css/bootstrap-treeview.css index d62bf7c7b..62ea91fc1 100644 --- a/src/css/bootstrap-treeview.css +++ b/src/css/bootstrap-treeview.css @@ -35,12 +35,3 @@ color: silver; cursor: not-allowed; } - -/* - Only valid when either options selectedColor or - selectedBackColor are left undefined -*/ -.treeview .node-selected { - background-color: #428bca !important; - color: #FFFFFF !important; -} \ No newline at end of file diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 8e1b82a7c..645601f7e 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -440,7 +440,7 @@ // Set element if (node.$el) { node.$el.addClass('node-selected'); - + if (node.selectedIcon || this.options.selectedIcon) { node.$el.children('span.node-icon') .removeClass(node.icon || this.options.nodeIcon) @@ -659,16 +659,6 @@ node.$el.empty(); } - - - // Set search result state - if (node.searchResult) { - node.$el.addClass('node-result'); - } - else { - node.$el.removeClass('node-result'); - } - // Set state based style overrides // node.$el.attr('style', this.buildStyleOverride(node)); @@ -811,6 +801,20 @@ '}'; } + if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { + + var innerStyle = '' + if (this.options.searchResultColor) { + innerStyle += 'color:' + this.options.searchResultColor + ';'; + } + if (this.options.searchResultBackColor) { + innerStyle += 'background-color:' + this.options.searchResultBackColor + ';'; + } + + style += '.node-' + this.elementId + '.node-result{' + innerStyle + '}'; + style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; + } + if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { var innerStyle = '' @@ -1201,7 +1205,7 @@ Tree.prototype.search = function (pattern, options) { options = $.extend({}, _default.searchOptions, options); - this.clearSearch({ render: false }); + this.clearSearch(); var results = []; if (pattern && pattern.length > 0) { @@ -1222,6 +1226,7 @@ // and when identifying result to be cleared $.each(results, function (index, node) { node.searchResult = true; + node.$el.addClass('node-result'); }) } @@ -1230,9 +1235,6 @@ if (options.revealResults) { this.revealNode(results); } - else { - this.render(); - } this.$element.trigger('searchComplete', $.extend(true, {}, results)); @@ -1248,11 +1250,8 @@ var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { node.searchResult = false; + node.$el.removeClass('node-result'); }); - - if (options.render) { - this.render(); - } this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; diff --git a/tests/lib/bootstrap-treeview.css b/tests/lib/bootstrap-treeview.css index d62bf7c7b..62ea91fc1 100644 --- a/tests/lib/bootstrap-treeview.css +++ b/tests/lib/bootstrap-treeview.css @@ -35,12 +35,3 @@ color: silver; cursor: not-allowed; } - -/* - Only valid when either options selectedColor or - selectedBackColor are left undefined -*/ -.treeview .node-selected { - background-color: #428bca !important; - color: #FFFFFF !important; -} \ No newline at end of file diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 8e1b82a7c..645601f7e 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -440,7 +440,7 @@ // Set element if (node.$el) { node.$el.addClass('node-selected'); - + if (node.selectedIcon || this.options.selectedIcon) { node.$el.children('span.node-icon') .removeClass(node.icon || this.options.nodeIcon) @@ -659,16 +659,6 @@ node.$el.empty(); } - - - // Set search result state - if (node.searchResult) { - node.$el.addClass('node-result'); - } - else { - node.$el.removeClass('node-result'); - } - // Set state based style overrides // node.$el.attr('style', this.buildStyleOverride(node)); @@ -811,6 +801,20 @@ '}'; } + if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { + + var innerStyle = '' + if (this.options.searchResultColor) { + innerStyle += 'color:' + this.options.searchResultColor + ';'; + } + if (this.options.searchResultBackColor) { + innerStyle += 'background-color:' + this.options.searchResultBackColor + ';'; + } + + style += '.node-' + this.elementId + '.node-result{' + innerStyle + '}'; + style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; + } + if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { var innerStyle = '' @@ -1201,7 +1205,7 @@ Tree.prototype.search = function (pattern, options) { options = $.extend({}, _default.searchOptions, options); - this.clearSearch({ render: false }); + this.clearSearch(); var results = []; if (pattern && pattern.length > 0) { @@ -1222,6 +1226,7 @@ // and when identifying result to be cleared $.each(results, function (index, node) { node.searchResult = true; + node.$el.addClass('node-result'); }) } @@ -1230,9 +1235,6 @@ if (options.revealResults) { this.revealNode(results); } - else { - this.render(); - } this.$element.trigger('searchComplete', $.extend(true, {}, results)); @@ -1248,11 +1250,8 @@ var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { node.searchResult = false; + node.$el.removeClass('node-result'); }); - - if (options.render) { - this.render(); - } this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; diff --git a/tests/tests.js b/tests/tests.js index 421b789e2..845bcee4c 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -863,9 +863,9 @@ // Check results are cleared $tree.treeview('search', [ 'Parent 1', { ignoreCase: false, exactMatch: true } ]); - equal($tree.find('.search-result').length, 1, 'Search results highlighted'); + equal($tree.find('.node-result').length, 1, 'Search results highlighted'); $tree.treeview('clearSearch'); - equal($tree.find('.search-result').length, 0, 'Search results cleared'); + equal($tree.find('.node-result').length, 0, 'Search results cleared'); // Check events fire ok(cbWorked, 'onSearchCleared function was called'); From 97dcc2f1445637e7ec5e78c232c0a3f786b3d76c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Fri, 26 Jun 2015 19:30:02 +0100 Subject: [PATCH 10/52] Missing node level styles overrides #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 54 +++++++++++---------------------- src/js/bootstrap-treeview.js | 54 +++++++++++---------------------- tests/lib/bootstrap-treeview.js | 54 +++++++++++---------------------- 4 files changed, 55 insertions(+), 109 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 280366f35..b01a7da79 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this.options.nodeIcon).addClass(b.selectedIcon||this.options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this.options.selectedIcon).addClass(b.icon||this.options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";if(this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSearchResults&&(this.options.searchResultColor||this.options.searchResultBackColor)){var b="";this.options.searchResultColor&&(b+="color:"+this.options.searchResultColor+";"),this.options.searchResultBackColor&&(b+="background-color:"+this.options.searchResultBackColor+";"),a+=".node-"+this.elementId+".node-result{"+b+"}",a+=".node-"+this.elementId+".node-result:hover{"+b+"}"}if(this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var b="";this.options.selectedColor&&(b+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(b+="background-color:"+this.options.selectedBackColor+";"),a+=".node-"+this.elementId+".node-selected{"+b+"}",a+=".node-"+this.elementId+".node-selected:hover{"+b+"}"}return this.css+a},g.prototype.template={tree:'
                                                    ',node:'
                                                  • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this.options.nodeIcon).addClass(b.selectedIcon||this.options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this.options.selectedIcon).addClass(b.icon||this.options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var b=".node-"+this.elementId+"{";if(this.options.color&&(b+="color:"+this.options.color+";"),this.options.backColor&&(b+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(b+="border:1px solid "+this.options.borderColor+";"):b+="border:none;",b+="}",this.options.onhoverColor&&(b+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSearchResults&&(this.options.searchResultColor||this.options.searchResultBackColor)){var c="";this.options.searchResultColor&&(c+="color:"+this.options.searchResultColor+";"),this.options.searchResultBackColor&&(c+="background-color:"+this.options.searchResultBackColor+";"),b+=".node-"+this.elementId+".node-result{"+c+"}",b+=".node-"+this.elementId+".node-result:hover{"+c+"}"}if(this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var c="";this.options.selectedColor&&(c+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(c+="background-color:"+this.options.selectedBackColor+";"),b+=".node-"+this.elementId+".node-selected{"+c+"}",b+=".node-"+this.elementId+".node-selected:hover{"+c+"}"}return a.each(this.nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this.elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this.css+b},g.prototype.template={tree:'
                                                      ',node:'
                                                    • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 645601f7e..536f72e23 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -658,10 +658,7 @@ // TODO Don't blanket empty, eval each action node.$el.empty(); } - - // Set state based style overrides - // node.$el.attr('style', this.buildStyleOverride(node)); - + // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { @@ -734,38 +731,6 @@ this._setDisabledState(node, node.state.disabled); }; - // Define any node level style override for - // 1. selectedNode - // 2. node|data assigned color overrides - // Tree.prototype.buildStyleOverride = function (node) { - - // if (node.state.disabled) return ''; - - // var color = node.color; - // var backColor = node.backColor; - - // // if (this.options.highlightSelected && node.state.selected) { - // // if (this.options.selectedColor) { - // // color = this.options.selectedColor; - // // } - // // if (this.options.selectedBackColor) { - // // backColor = this.options.selectedBackColor; - // // } - // // } - - // if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { - // if (this.options.searchResultColor) { - // color = this.options.searchResultColor; - // } - // if (this.options.searchResultBackColor) { - // backColor = this.options.searchResultBackColor; - // } - // } - - // // return 'color:' + color + - // // ';background-color:' + backColor + ';'; - // }; - // Add inline style into head Tree.prototype.injectStyle = function () { @@ -779,6 +744,7 @@ var style = '.node-' + this.elementId + '{'; + // Basic bootstrap style overrides if (this.options.color) { style += 'color:' + this.options.color + ';'; } @@ -801,6 +767,7 @@ '}'; } + // Style search results if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { var innerStyle = '' @@ -815,6 +782,7 @@ style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; } + // Style selected nodes if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { var innerStyle = '' @@ -829,6 +797,20 @@ style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; } + // Node level style overrides + $.each(this.nodes, $.proxy(function (index, node) { + if (node.color || node.backColor) { + var innerStyle = ''; + if (node.color) { + innerStyle += 'color:' + node.color + ';'; + } + if (node.backColor) { + innerStyle += 'background-color:' + node.backColor + ';'; + } + style += '.node-' + this.elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + } + }, this)); + return this.css + style; }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 645601f7e..536f72e23 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -658,10 +658,7 @@ // TODO Don't blanket empty, eval each action node.$el.empty(); } - - // Set state based style overrides - // node.$el.attr('style', this.buildStyleOverride(node)); - + // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { @@ -734,38 +731,6 @@ this._setDisabledState(node, node.state.disabled); }; - // Define any node level style override for - // 1. selectedNode - // 2. node|data assigned color overrides - // Tree.prototype.buildStyleOverride = function (node) { - - // if (node.state.disabled) return ''; - - // var color = node.color; - // var backColor = node.backColor; - - // // if (this.options.highlightSelected && node.state.selected) { - // // if (this.options.selectedColor) { - // // color = this.options.selectedColor; - // // } - // // if (this.options.selectedBackColor) { - // // backColor = this.options.selectedBackColor; - // // } - // // } - - // if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { - // if (this.options.searchResultColor) { - // color = this.options.searchResultColor; - // } - // if (this.options.searchResultBackColor) { - // backColor = this.options.searchResultBackColor; - // } - // } - - // // return 'color:' + color + - // // ';background-color:' + backColor + ';'; - // }; - // Add inline style into head Tree.prototype.injectStyle = function () { @@ -779,6 +744,7 @@ var style = '.node-' + this.elementId + '{'; + // Basic bootstrap style overrides if (this.options.color) { style += 'color:' + this.options.color + ';'; } @@ -801,6 +767,7 @@ '}'; } + // Style search results if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { var innerStyle = '' @@ -815,6 +782,7 @@ style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; } + // Style selected nodes if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { var innerStyle = '' @@ -829,6 +797,20 @@ style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; } + // Node level style overrides + $.each(this.nodes, $.proxy(function (index, node) { + if (node.color || node.backColor) { + var innerStyle = ''; + if (node.color) { + innerStyle += 'color:' + node.color + ';'; + } + if (node.backColor) { + innerStyle += 'background-color:' + node.backColor + ';'; + } + style += '.node-' + this.elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + } + }, this)); + return this.css + style; }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 645601f7e..536f72e23 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -658,10 +658,7 @@ // TODO Don't blanket empty, eval each action node.$el.empty(); } - - // Set state based style overrides - // node.$el.attr('style', this.buildStyleOverride(node)); - + // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { @@ -734,38 +731,6 @@ this._setDisabledState(node, node.state.disabled); }; - // Define any node level style override for - // 1. selectedNode - // 2. node|data assigned color overrides - // Tree.prototype.buildStyleOverride = function (node) { - - // if (node.state.disabled) return ''; - - // var color = node.color; - // var backColor = node.backColor; - - // // if (this.options.highlightSelected && node.state.selected) { - // // if (this.options.selectedColor) { - // // color = this.options.selectedColor; - // // } - // // if (this.options.selectedBackColor) { - // // backColor = this.options.selectedBackColor; - // // } - // // } - - // if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { - // if (this.options.searchResultColor) { - // color = this.options.searchResultColor; - // } - // if (this.options.searchResultBackColor) { - // backColor = this.options.searchResultBackColor; - // } - // } - - // // return 'color:' + color + - // // ';background-color:' + backColor + ';'; - // }; - // Add inline style into head Tree.prototype.injectStyle = function () { @@ -779,6 +744,7 @@ var style = '.node-' + this.elementId + '{'; + // Basic bootstrap style overrides if (this.options.color) { style += 'color:' + this.options.color + ';'; } @@ -801,6 +767,7 @@ '}'; } + // Style search results if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { var innerStyle = '' @@ -815,6 +782,7 @@ style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; } + // Style selected nodes if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { var innerStyle = '' @@ -829,6 +797,20 @@ style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; } + // Node level style overrides + $.each(this.nodes, $.proxy(function (index, node) { + if (node.color || node.backColor) { + var innerStyle = ''; + if (node.color) { + innerStyle += 'color:' + node.color + ';'; + } + if (node.backColor) { + innerStyle += 'background-color:' + node.backColor + ';'; + } + style += '.node-' + this.elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + } + }, this)); + return this.css + style; }; From c075dbc56e481d786800630d7f86b5a11e36ff1c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Fri, 26 Jun 2015 19:58:34 +0100 Subject: [PATCH 11/52] Tidy up --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 454 +++++++++++++++----------------- src/js/bootstrap-treeview.js | 454 +++++++++++++++----------------- tests/lib/bootstrap-treeview.js | 454 +++++++++++++++----------------- 4 files changed, 652 insertions(+), 712 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index b01a7da79..77159732b 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],this.initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.expandIcon).addClass(this.options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this.options.collapseIcon).addClass(this.options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){console.log("recurse children"),this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this.options.nodeIcon).addClass(b.selectedIcon||this.options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this.options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this.options.selectedIcon).addClass(b.icon||this.options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.uncheckedIcon).addClass(this.options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this.options.checkedIcon).addClass(this.options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){console.log("RENDER"),this.initialized||(this.$wrapper=a(this.template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this.injectStyle(),this.initialized=!0),this.tree&&a.each(this.tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._newNodeEl=function(b){var c=a(this.template.node);return b?(console.log("insert - "+b.text()),this.$wrapper.children().eq(b.index()).after(c)):(console.log("append"),this.$wrapper.append(c)),c},g.prototype._collapseNode=function(b){b.nodes&&(console.log("collapseNode - "+b.text),a.each(b.nodes,a.proxy(function(a,b){this._collapseNode(b),b.$el&&(b.$el.remove(),b.$el=null)},this)))},g.prototype._expandNode=function(b){if(b.nodes){console.log("expandNode - "+b.text);var c=b.$el;a.each(b.nodes.slice(0).reverse(),a.proxy(function(a,d){console.log("expandNode child "+b.text+" > "+d.text),d.level=b.level+1,this._renderNode(d,c)},this))}},g.prototype._renderNode=function(b,c){if(console.log("renderNode - "+b.text),b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this.elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this.buildStyle()+" ").appendTo("head")},g.prototype.buildStyle=function(){var b=".node-"+this.elementId+"{";if(this.options.color&&(b+="color:"+this.options.color+";"),this.options.backColor&&(b+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(b+="border:1px solid "+this.options.borderColor+";"):b+="border:none;",b+="}",this.options.onhoverColor&&(b+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.options.highlightSearchResults&&(this.options.searchResultColor||this.options.searchResultBackColor)){var c="";this.options.searchResultColor&&(c+="color:"+this.options.searchResultColor+";"),this.options.searchResultBackColor&&(c+="background-color:"+this.options.searchResultBackColor+";"),b+=".node-"+this.elementId+".node-result{"+c+"}",b+=".node-"+this.elementId+".node-result:hover{"+c+"}"}if(this.options.highlightSelected&&(this.options.selectedColor||this.options.selectedBackColor)){var c="";this.options.selectedColor&&(c+="color:"+this.options.selectedColor+";"),this.options.selectedBackColor&&(c+="background-color:"+this.options.selectedBackColor+";"),b+=".node-"+this.elementId+".node-selected{"+c+"}",b+=".node-"+this.elementId+".node-selected:hover{"+c+"}"}return a.each(this.nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this.elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this.css+b},g.prototype.template={tree:'
                                                        ',node:'
                                                      • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this.tree,b)},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this.tree,b)},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){console.log("test - "+b.text),this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                          ',node:'
                                                        • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this._findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 536f72e23..cb6675e5b 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -86,19 +86,19 @@ var Tree = function (element, options) { this.$element = $(element); - this.elementId = element.id; - this.styleId = this.elementId + '-style'; + this._elementId = element.id; + this._styleId = this._elementId + '-style'; - this.init(options); + this._init(options); return { // Options (public access) - options: this.options, + options: this._options, // Initialize / destroy methods - init: $.proxy(this.init, this), - remove: $.proxy(this.remove, this), + init: $.proxy(this._init, this), + remove: $.proxy(this._remove, this), // Get methods getNode: $.proxy(this.getNode, this), @@ -146,48 +146,48 @@ }; }; - Tree.prototype.init = function (options) { + Tree.prototype._init = function (options) { - this.tree = []; - this.nodes = []; - this.initialized = false; + this._tree = []; + this._nodes = []; + this._initialized = false; if (options.data) { if (typeof options.data === 'string') { options.data = $.parseJSON(options.data); } - this.tree = $.extend(true, [], options.data); + this._tree = $.extend(true, [], options.data); delete options.data; } - this.options = $.extend({}, _default.settings, options); + this._options = $.extend({}, _default.settings, options); - this.destroy(); - this.subscribeEvents(); - this.setInitialStates({ nodes: this.tree }, 0); - this.render(); + this._destroy(); + this._subscribeEvents(); + this._setInitialStates({ nodes: this._tree }, 0); + this._render(); }; - Tree.prototype.remove = function () { - this.destroy(); + Tree.prototype._remove = function () { + this._destroy(); $.removeData(this, pluginName); - $('#' + this.styleId).remove(); + $('#' + this._styleId).remove(); }; - Tree.prototype.destroy = function () { + Tree.prototype._destroy = function () { - if (!this.initialized) return; + if (!this._initialized) return; this.$wrapper.remove(); this.$wrapper = null; // Switch off events - this.unsubscribeEvents(); + this._unsubscribeEvents(); - // Reset this.initialized flag - this.initialized = false; + // Reset this._initialized flag + this._initialized = false; }; - Tree.prototype.unsubscribeEvents = function () { + Tree.prototype._unsubscribeEvents = function () { this.$element.off('click'); this.$element.off('nodeChecked'); @@ -202,50 +202,50 @@ this.$element.off('searchCleared'); }; - Tree.prototype.subscribeEvents = function () { + Tree.prototype._subscribeEvents = function () { - this.unsubscribeEvents(); + this._unsubscribeEvents(); - this.$element.on('click', $.proxy(this.clickHandler, this)); + this.$element.on('click', $.proxy(this._clickHandler, this)); - if (typeof (this.options.onNodeChecked) === 'function') { - this.$element.on('nodeChecked', this.options.onNodeChecked); + if (typeof (this._options.onNodeChecked) === 'function') { + this.$element.on('nodeChecked', this._options.onNodeChecked); } - if (typeof (this.options.onNodeCollapsed) === 'function') { - this.$element.on('nodeCollapsed', this.options.onNodeCollapsed); + if (typeof (this._options.onNodeCollapsed) === 'function') { + this.$element.on('nodeCollapsed', this._options.onNodeCollapsed); } - if (typeof (this.options.onNodeDisabled) === 'function') { - this.$element.on('nodeDisabled', this.options.onNodeDisabled); + if (typeof (this._options.onNodeDisabled) === 'function') { + this.$element.on('nodeDisabled', this._options.onNodeDisabled); } - if (typeof (this.options.onNodeEnabled) === 'function') { - this.$element.on('nodeEnabled', this.options.onNodeEnabled); + if (typeof (this._options.onNodeEnabled) === 'function') { + this.$element.on('nodeEnabled', this._options.onNodeEnabled); } - if (typeof (this.options.onNodeExpanded) === 'function') { - this.$element.on('nodeExpanded', this.options.onNodeExpanded); + if (typeof (this._options.onNodeExpanded) === 'function') { + this.$element.on('nodeExpanded', this._options.onNodeExpanded); } - if (typeof (this.options.onNodeSelected) === 'function') { - this.$element.on('nodeSelected', this.options.onNodeSelected); + if (typeof (this._options.onNodeSelected) === 'function') { + this.$element.on('nodeSelected', this._options.onNodeSelected); } - if (typeof (this.options.onNodeUnchecked) === 'function') { - this.$element.on('nodeUnchecked', this.options.onNodeUnchecked); + if (typeof (this._options.onNodeUnchecked) === 'function') { + this.$element.on('nodeUnchecked', this._options.onNodeUnchecked); } - if (typeof (this.options.onNodeUnselected) === 'function') { - this.$element.on('nodeUnselected', this.options.onNodeUnselected); + if (typeof (this._options.onNodeUnselected) === 'function') { + this.$element.on('nodeUnselected', this._options.onNodeUnselected); } - if (typeof (this.options.onSearchComplete) === 'function') { - this.$element.on('searchComplete', this.options.onSearchComplete); + if (typeof (this._options.onSearchComplete) === 'function') { + this.$element.on('searchComplete', this._options.onSearchComplete); } - if (typeof (this.options.onSearchCleared) === 'function') { - this.$element.on('searchCleared', this.options.onSearchCleared); + if (typeof (this._options.onSearchCleared) === 'function') { + this.$element.on('searchCleared', this._options.onSearchCleared); } }; @@ -255,7 +255,7 @@ For performance we also take this opportunity to index nodes in a flattened structure */ - Tree.prototype.setInitialStates = function (node, level) { + Tree.prototype._setInitialStates = function (node, level) { if (!node.nodes) return; level += 1; @@ -265,7 +265,7 @@ $.each(node.nodes, function checkStates(index, node) { // nodeId : unique, incremental identifier - node.nodeId = _this.nodes.length; + node.nodeId = _this._nodes.length; // parentId : transversing up the tree node.parentId = parent.nodeId; @@ -291,7 +291,7 @@ // set expanded state; if not provided based on levels if (!node.state.hasOwnProperty('expanded')) { if (!node.state.disabled && - (level < _this.options.levels) && + (level < _this._options.levels) && (node.nodes && node.nodes.length > 0)) { node.state.expanded = true; } @@ -306,21 +306,21 @@ } // index nodes in a flattened structure for use later - _this.nodes.push(node); + _this._nodes.push(node); // recurse child nodes and transverse the tree if (node.nodes) { - _this.setInitialStates(node, level); + _this._setInitialStates(node, level); } }); }; - Tree.prototype.clickHandler = function (event) { + Tree.prototype._clickHandler = function (event) { - if (!this.options.enableLinks) event.preventDefault(); + if (!this._options.enableLinks) event.preventDefault(); var target = $(event.target); - var node = this.findNode(target); + var node = this.targetNode(target); if (!node || node.state.disabled) return; var classList = target.attr('class') ? target.attr('class').split(' ') : []; @@ -341,10 +341,10 @@ // Looks up the DOM for the closest parent list item to retrieve the // data attribute nodeid, which is used to lookup the node in the flattened structure. - Tree.prototype.findNode = function (target) { + Tree.prototype.targetNode = function (target) { var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); - var node = this.nodes[nodeId]; + var node = this._nodes[nodeId]; if (!node) { console.log('Error: node does not exist'); @@ -371,8 +371,8 @@ // Set element if (node.$el) { node.$el.children('span.expand-icon') - .removeClass(this.options.expandIcon) - .addClass(this.options.collapseIcon); + .removeClass(this._options.expandIcon) + .addClass(this._options.collapseIcon); } // Render child nodes @@ -391,14 +391,13 @@ // Set element if (node.$el) { node.$el.children('span.expand-icon') - .removeClass(this.options.collapseIcon) - .addClass(this.options.expandIcon); + .removeClass(this._options.collapseIcon) + .addClass(this._options.expandIcon); } // Collapse children if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { - console.log('recurse children') this._setExpandedState(node, false, options); }, this)); } @@ -428,8 +427,8 @@ if (state) { // If multiSelect false, unselect previously selected - if (!this.options.multiSelect) { - $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + if (!this._options.multiSelect) { + $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { this._setSelectedState(node, false, options); }, this)); } @@ -441,10 +440,10 @@ if (node.$el) { node.$el.addClass('node-selected'); - if (node.selectedIcon || this.options.selectedIcon) { + if (node.selectedIcon || this._options.selectedIcon) { node.$el.children('span.node-icon') - .removeClass(node.icon || this.options.nodeIcon) - .addClass(node.selectedIcon || this.options.selectedIcon); + .removeClass(node.icon || this._options.nodeIcon) + .addClass(node.selectedIcon || this._options.selectedIcon); } } @@ -462,10 +461,10 @@ if (node.$el) { node.$el.removeClass('node-selected'); - if (node.selectedIcon || this.options.selectedIcon) { + if (node.selectedIcon || this._options.selectedIcon) { node.$el.children('span.node-icon') - .removeClass(node.selectedIcon || this.options.selectedIcon) - .addClass(node.icon || this.options.nodeIcon); + .removeClass(node.selectedIcon || this._options.selectedIcon) + .addClass(node.icon || this._options.nodeIcon); } } @@ -498,8 +497,8 @@ if (node.$el) { node.$el.addClass('node-checked'); node.$el.children('span.check-icon') - .removeClass(this.options.uncheckedIcon) - .addClass(this.options.checkedIcon); + .removeClass(this._options.uncheckedIcon) + .addClass(this._options.checkedIcon); } // Optionally trigger event @@ -516,8 +515,8 @@ if (node.$el) { node.$el.removeClass('node-checked'); node.$el.children('span.check-icon') - .removeClass(this.options.checkedIcon) - .addClass(this.options.uncheckedIcon); + .removeClass(this._options.checkedIcon) + .addClass(this._options.uncheckedIcon); } // Optionally trigger event @@ -570,80 +569,32 @@ } }; - Tree.prototype.render = function () { + Tree.prototype._render = function () { - console.log('RENDER'); - - if (!this.initialized) { + if (!this._initialized) { // Setup first time only components - this.$wrapper = $(this.template.tree); + this.$wrapper = $(this._template.tree); this.$element.empty() .addClass(pluginName) .append(this.$wrapper); - this.injectStyle(); + this._injectStyle(); - this.initialized = true; + this._initialized = true; } - if (!this.tree) return; + if (!this._tree) return; - $.each(this.tree, $.proxy(function addRootNodes(id, node) { + $.each(this._tree, $.proxy(function addRootNodes(id, node) { node.level = 1; this._renderNode(node); }, this)); }; - // Creates a new node element from template and - // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (pEl) { - - var $el = $(this.template.node); - - if (pEl) { - console.log('insert - ' + pEl.text()); - this.$wrapper.children().eq(pEl.index()).after($el); - } - else { - console.log('append'); - this.$wrapper.append($el); - } - - return $el; - }; - - Tree.prototype._collapseNode = function (node) { - if (!node.nodes) return; - - console.log('collapseNode - ' + node.text); - $.each(node.nodes, $.proxy(function (index, node) { - this._collapseNode(node); - if (node.$el) { - node.$el.remove(); - node.$el = null; - } - }, this)); - }; - - Tree.prototype._expandNode = function (node) { - if (!node.nodes) return; - - console.log('expandNode - ' + node.text); - var $pEl = node.$el; - $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { - console.log('expandNode child ' + node.text + ' > ' + childNode.text); - childNode.level = node.level + 1; - this._renderNode(childNode, $pEl); - // $pEl = childNode.$el; - }, this)); - }; - Tree.prototype._renderNode = function (node, pEl) { - console.log('renderNode - ' + node.text); if (!node) return; - // console.log(node); if (!node.$el) { // New node, needs a new element @@ -651,56 +602,45 @@ // One time setup node.$el - .addClass('node-' + this.elementId) + .addClass('node-' + this._elementId) .attr('data-nodeid', node.nodeId); } else { - // TODO Don't blanket empty, eval each action node.$el.empty(); } - // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { - node.$el.append(this.template.indent); - } - - // Add expand, collapse or empty spacer icons - var classList = []; - if (node.nodes) { - classList.push('expand-icon'); - } - else { - classList.push(this.options.emptyIcon); + node.$el.append(this._template.indent); } + // Add expand / collapse or empty spacer icons node.$el - .append($(this.template.icon) - .addClass(classList.join(' ')) + .append($(this._template.icon) + .addClass(node.nodes ? 'expand-icon' : this._options.emptyIcon) ); - // Add node icon - if (this.options.showIcon) { + if (this._options.showIcon) { node.$el - .append($(this.template.icon) + .append($(this._template.icon) .addClass('node-icon') - .addClass(node.icon || this.options.nodeIcon) + .addClass(node.icon || this._options.nodeIcon) ); } // Add checkable icon - if (this.options.showCheckbox) { + if (this._options.showCheckbox) { node.$el - .append($(this.template.icon) + .append($(this._template.icon) .addClass('check-icon') ); } // Add text - if (this.options.enableLinks) { + if (this._options.enableLinks) { node.$el - .append($(this.template.link) + .append($(this._template.link) .attr('href', node.href) .append(node.text) ); @@ -711,10 +651,10 @@ } // Add tags as badges - if (this.options.showTags && node.tags) { + if (this._options.showTags && node.tags) { $.each(node.tags, $.proxy(function addTag(id, tag) { node.$el - .append($(this.template.badge) + .append($(this._template.badge) .append(tag) ); }, this)); @@ -731,74 +671,115 @@ this._setDisabledState(node, node.state.disabled); }; + // Creates a new node element from template and + // ensures the template is inserted at the correct position + Tree.prototype._newNodeEl = function (pEl) { + + var $el = $(this._template.node); + + if (pEl) { + this.$wrapper.children() + .eq(pEl.index()).after($el); + } + else { + this.$wrapper.append($el); + } + + return $el; + }; + + // Collapse node, removing it's immediate children + Tree.prototype._collapseNode = function (node) { + if (!node.nodes) return; + + $.each(node.nodes, $.proxy(function (index, node) { + this._collapseNode(node); + if (node.$el) { + node.$el.remove(); + node.$el = null; + } + }, this)); + }; + + // Expand node, rendering it's immediate children + Tree.prototype._expandNode = function (node) { + if (!node.nodes) return; + + var $pEl = node.$el; + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, $pEl); + }, this)); + }; + // Add inline style into head - Tree.prototype.injectStyle = function () { + Tree.prototype._injectStyle = function () { - if (this.options.injectStyle && !document.getElementById(this.styleId)) { - $('').appendTo('head'); + if (this._options.injectStyle && !document.getElementById(this._styleId)) { + $('').appendTo('head'); } }; // Construct trees style based on user options - Tree.prototype.buildStyle = function () { + Tree.prototype._buildStyle = function () { - var style = '.node-' + this.elementId + '{'; + var style = '.node-' + this._elementId + '{'; // Basic bootstrap style overrides - if (this.options.color) { - style += 'color:' + this.options.color + ';'; + if (this._options.color) { + style += 'color:' + this._options.color + ';'; } - if (this.options.backColor) { - style += 'background-color:' + this.options.backColor + ';'; + if (this._options.backColor) { + style += 'background-color:' + this._options.backColor + ';'; } - if (!this.options.showBorder) { + if (!this._options.showBorder) { style += 'border:none;'; } - else if (this.options.borderColor) { - style += 'border:1px solid ' + this.options.borderColor + ';'; + else if (this._options.borderColor) { + style += 'border:1px solid ' + this._options.borderColor + ';'; } style += '}'; - if (this.options.onhoverColor) { - style += '.node-' + this.elementId + ':not(.node-disabled):hover{' + - 'background-color:' + this.options.onhoverColor + ';' + + if (this._options.onhoverColor) { + style += '.node-' + this._elementId + ':not(.node-disabled):hover{' + + 'background-color:' + this._options.onhoverColor + ';' + '}'; } // Style search results - if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { + if (this._options.highlightSearchResults && (this._options.searchResultColor || this._options.searchResultBackColor)) { var innerStyle = '' - if (this.options.searchResultColor) { - innerStyle += 'color:' + this.options.searchResultColor + ';'; + if (this._options.searchResultColor) { + innerStyle += 'color:' + this._options.searchResultColor + ';'; } - if (this.options.searchResultBackColor) { - innerStyle += 'background-color:' + this.options.searchResultBackColor + ';'; + if (this._options.searchResultBackColor) { + innerStyle += 'background-color:' + this._options.searchResultBackColor + ';'; } - style += '.node-' + this.elementId + '.node-result{' + innerStyle + '}'; - style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-result{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-result:hover{' + innerStyle + '}'; } // Style selected nodes - if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { + if (this._options.highlightSelected && (this._options.selectedColor || this._options.selectedBackColor)) { var innerStyle = '' - if (this.options.selectedColor) { - innerStyle += 'color:' + this.options.selectedColor + ';'; + if (this._options.selectedColor) { + innerStyle += 'color:' + this._options.selectedColor + ';'; } - if (this.options.selectedBackColor) { - innerStyle += 'background-color:' + this.options.selectedBackColor + ';'; + if (this._options.selectedBackColor) { + innerStyle += 'background-color:' + this._options.selectedBackColor + ';'; } - style += '.node-' + this.elementId + '.node-selected{' + innerStyle + '}'; - style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-selected{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-selected:hover{' + innerStyle + '}'; } // Node level style overrides - $.each(this.nodes, $.proxy(function (index, node) { + $.each(this._nodes, $.proxy(function (index, node) { if (node.color || node.backColor) { var innerStyle = ''; if (node.color) { @@ -807,14 +788,14 @@ if (node.backColor) { innerStyle += 'background-color:' + node.backColor + ';'; } - style += '.node-' + this.elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + style += '.node-' + this._elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; } }, this)); - return this.css + style; + return this._css + style; }; - Tree.prototype.template = { + Tree.prototype._template = { tree: '
                                                            ', node: '
                                                          • ', indent: '', @@ -823,7 +804,7 @@ badge: '' }; - Tree.prototype.css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' + Tree.prototype._css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' /** @@ -832,7 +813,7 @@ @return {Object} node - Matching node */ Tree.prototype.getNode = function (nodeId) { - return this.nodes[nodeId]; + return this._nodes[nodeId]; }; /** @@ -841,8 +822,8 @@ @returns {Object} node - The parent node */ Tree.prototype.getParent = function (identifier) { - var node = this.identifyNode(identifier); - return this.nodes[node.parentId]; + var node = this._identifyNode(identifier); + return this._nodes[node.parentId]; }; /** @@ -851,9 +832,9 @@ @returns {Array} nodes - Sibling nodes */ Tree.prototype.getSiblings = function (identifier) { - var node = this.identifyNode(identifier); + var node = this._identifyNode(identifier); var parent = this.getParent(node); - var nodes = parent ? parent.nodes : this.tree; + var nodes = parent ? parent.nodes : this._tree; return nodes.filter(function (obj) { return obj.nodeId !== node.nodeId; }); @@ -864,7 +845,7 @@ @returns {Array} nodes - Selected nodes */ Tree.prototype.getSelected = function () { - return this.findNodes('true', 'g', 'state.selected'); + return this._findNodes('true', 'g', 'state.selected'); }; /** @@ -872,7 +853,7 @@ @returns {Array} nodes - Unselected nodes */ Tree.prototype.getUnselected = function () { - return this.findNodes('false', 'g', 'state.selected'); + return this._findNodes('false', 'g', 'state.selected'); }; /** @@ -880,7 +861,7 @@ @returns {Array} nodes - Expanded nodes */ Tree.prototype.getExpanded = function () { - return this.findNodes('true', 'g', 'state.expanded'); + return this._findNodes('true', 'g', 'state.expanded'); }; /** @@ -888,7 +869,7 @@ @returns {Array} nodes - Collapsed nodes */ Tree.prototype.getCollapsed = function () { - return this.findNodes('false', 'g', 'state.expanded'); + return this._findNodes('false', 'g', 'state.expanded'); }; /** @@ -896,7 +877,7 @@ @returns {Array} nodes - Checked nodes */ Tree.prototype.getChecked = function () { - return this.findNodes('true', 'g', 'state.checked'); + return this._findNodes('true', 'g', 'state.checked'); }; /** @@ -904,7 +885,7 @@ @returns {Array} nodes - Unchecked nodes */ Tree.prototype.getUnchecked = function () { - return this.findNodes('false', 'g', 'state.checked'); + return this._findNodes('false', 'g', 'state.checked'); }; /** @@ -912,7 +893,7 @@ @returns {Array} nodes - Disabled nodes */ Tree.prototype.getDisabled = function () { - return this.findNodes('true', 'g', 'state.disabled'); + return this._findNodes('true', 'g', 'state.disabled'); }; /** @@ -920,7 +901,7 @@ @returns {Array} nodes - Enabled nodes */ Tree.prototype.getEnabled = function () { - return this.findNodes('false', 'g', 'state.disabled'); + return this._findNodes('false', 'g', 'state.disabled'); }; @@ -930,7 +911,7 @@ @param {optional Object} options */ Tree.prototype.selectNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setSelectedState(node, true, options); }, this)); }; @@ -941,7 +922,7 @@ @param {optional Object} options */ Tree.prototype.unselectNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setSelectedState(node, false, options); }, this)); }; @@ -952,7 +933,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleSelectedState(node, options); }, this)); }; @@ -965,7 +946,7 @@ Tree.prototype.collapseAll = function (options) { options = $.extend({}, _default.options, options); options.levels = options.levels || 999; - this.collapseNode(this.tree, options); + this.collapseNode(this._tree, options); }; /** @@ -974,7 +955,7 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setExpandedState(node, false, options); }, this)); }; @@ -986,7 +967,7 @@ Tree.prototype.expandAll = function (options) { options = $.extend({}, _default.options, options); options.levels = options.levels || 999; - this.expandNode(this.tree, options); + this.expandNode(this._tree, options); }; /** @@ -995,7 +976,7 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); @@ -1005,7 +986,6 @@ Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { - console.log('test - ' + node.text); this._setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); @@ -1019,7 +999,7 @@ @param {optional Object} options */ Tree.prototype.revealNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { var parentNode = node; var tmpNode; while (tmpNode = this.getParent(parentNode)) { @@ -1035,7 +1015,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleExpandedState(node, options); }, this)); }; @@ -1046,8 +1026,8 @@ @param {optional Object} options */ Tree.prototype.checkAll = function (options) { - var identifiers = this.findNodes('false', 'g', 'state.checked'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('false', 'g', 'state.checked'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, true, options); }, this)); }; @@ -1058,7 +1038,7 @@ @param {optional Object} options */ Tree.prototype.checkNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, true, options); }, this)); }; @@ -1068,8 +1048,8 @@ @param {optional Object} options */ Tree.prototype.uncheckAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.checked'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('true', 'g', 'state.checked'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, false, options); }, this)); }; @@ -1080,7 +1060,7 @@ @param {optional Object} options */ Tree.prototype.uncheckNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, false, options); }, this)); }; @@ -1091,7 +1071,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleCheckedState(node, options); }, this)); }; @@ -1102,8 +1082,8 @@ @param {optional Object} options */ Tree.prototype.disableAll = function (options) { - var identifiers = this.findNodes('false', 'g', 'state.disabled'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('false', 'g', 'state.disabled'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, true, options); }, this)); }; @@ -1114,7 +1094,7 @@ @param {optional Object} options */ Tree.prototype.disableNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, true, options); }, this)); }; @@ -1124,8 +1104,8 @@ @param {optional Object} options */ Tree.prototype.enableAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.disabled'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('true', 'g', 'state.disabled'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, false, options); }, this)); }; @@ -1136,7 +1116,7 @@ @param {optional Object} options */ Tree.prototype.enableNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, false, options); }, this)); }; @@ -1147,7 +1127,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, !node.state.disabled, options); }, this)); }; @@ -1156,7 +1136,7 @@ /** Common code for processing multiple identifiers */ - Tree.prototype.forEachIdentifier = function (identifiers, options, callback) { + Tree.prototype._forEachIdentifier = function (identifiers, options, callback) { options = $.extend({}, _default.options, options); @@ -1165,16 +1145,16 @@ } $.each(identifiers, $.proxy(function (index, identifier) { - callback(this.identifyNode(identifier), options); + callback(this._identifyNode(identifier), options); }, this)); }; /* Identifies a node from either a node id or object */ - Tree.prototype.identifyNode = function (identifier) { + Tree.prototype._identifyNode = function (identifier) { return ((typeof identifier) === 'number') ? - this.nodes[identifier] : + this._nodes[identifier] : identifier; }; @@ -1201,7 +1181,7 @@ modifier += 'i'; } - results = this.findNodes(pattern, modifier); + results = this._findNodes(pattern, modifier); // Add searchResult property to all matching nodes // This will be used to apply custom styles @@ -1230,7 +1210,7 @@ options = $.extend({}, { render: true }, options); - var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { + var results = $.each(this._findNodes('true', 'g', 'searchResult'), function (index, node) { node.searchResult = false; node.$el.removeClass('node-result'); }); @@ -1245,14 +1225,14 @@ @param {optional String} attribute - Attribute to compare pattern against @return {Array} nodes - Nodes that match your criteria */ - Tree.prototype.findNodes = function (pattern, modifier, attribute) { + Tree.prototype._findNodes = function (pattern, modifier, attribute) { modifier = modifier || 'g'; attribute = attribute || 'text'; var _this = this; - return $.grep(this.nodes, function (node) { - var val = _this.getNodeValue(node, attribute); + return $.grep(this._nodes, function (node) { + var val = _this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } @@ -1266,12 +1246,12 @@ @param {String} attr - Identifies an object property using dot notation @return {String} value - Matching attributes string representation */ - Tree.prototype.getNodeValue = function (obj, attr) { + Tree.prototype._getNodeValue = function (obj, attr) { var index = attr.indexOf('.'); if (index > 0) { var _obj = obj[attr.substring(0, index)]; var _attr = attr.substring(index + 1, attr.length); - return this.getNodeValue(_obj, _attr); + return this._getNodeValue(_obj, _attr); } else { if (obj.hasOwnProperty(attr)) { diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 536f72e23..cb6675e5b 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -86,19 +86,19 @@ var Tree = function (element, options) { this.$element = $(element); - this.elementId = element.id; - this.styleId = this.elementId + '-style'; + this._elementId = element.id; + this._styleId = this._elementId + '-style'; - this.init(options); + this._init(options); return { // Options (public access) - options: this.options, + options: this._options, // Initialize / destroy methods - init: $.proxy(this.init, this), - remove: $.proxy(this.remove, this), + init: $.proxy(this._init, this), + remove: $.proxy(this._remove, this), // Get methods getNode: $.proxy(this.getNode, this), @@ -146,48 +146,48 @@ }; }; - Tree.prototype.init = function (options) { + Tree.prototype._init = function (options) { - this.tree = []; - this.nodes = []; - this.initialized = false; + this._tree = []; + this._nodes = []; + this._initialized = false; if (options.data) { if (typeof options.data === 'string') { options.data = $.parseJSON(options.data); } - this.tree = $.extend(true, [], options.data); + this._tree = $.extend(true, [], options.data); delete options.data; } - this.options = $.extend({}, _default.settings, options); + this._options = $.extend({}, _default.settings, options); - this.destroy(); - this.subscribeEvents(); - this.setInitialStates({ nodes: this.tree }, 0); - this.render(); + this._destroy(); + this._subscribeEvents(); + this._setInitialStates({ nodes: this._tree }, 0); + this._render(); }; - Tree.prototype.remove = function () { - this.destroy(); + Tree.prototype._remove = function () { + this._destroy(); $.removeData(this, pluginName); - $('#' + this.styleId).remove(); + $('#' + this._styleId).remove(); }; - Tree.prototype.destroy = function () { + Tree.prototype._destroy = function () { - if (!this.initialized) return; + if (!this._initialized) return; this.$wrapper.remove(); this.$wrapper = null; // Switch off events - this.unsubscribeEvents(); + this._unsubscribeEvents(); - // Reset this.initialized flag - this.initialized = false; + // Reset this._initialized flag + this._initialized = false; }; - Tree.prototype.unsubscribeEvents = function () { + Tree.prototype._unsubscribeEvents = function () { this.$element.off('click'); this.$element.off('nodeChecked'); @@ -202,50 +202,50 @@ this.$element.off('searchCleared'); }; - Tree.prototype.subscribeEvents = function () { + Tree.prototype._subscribeEvents = function () { - this.unsubscribeEvents(); + this._unsubscribeEvents(); - this.$element.on('click', $.proxy(this.clickHandler, this)); + this.$element.on('click', $.proxy(this._clickHandler, this)); - if (typeof (this.options.onNodeChecked) === 'function') { - this.$element.on('nodeChecked', this.options.onNodeChecked); + if (typeof (this._options.onNodeChecked) === 'function') { + this.$element.on('nodeChecked', this._options.onNodeChecked); } - if (typeof (this.options.onNodeCollapsed) === 'function') { - this.$element.on('nodeCollapsed', this.options.onNodeCollapsed); + if (typeof (this._options.onNodeCollapsed) === 'function') { + this.$element.on('nodeCollapsed', this._options.onNodeCollapsed); } - if (typeof (this.options.onNodeDisabled) === 'function') { - this.$element.on('nodeDisabled', this.options.onNodeDisabled); + if (typeof (this._options.onNodeDisabled) === 'function') { + this.$element.on('nodeDisabled', this._options.onNodeDisabled); } - if (typeof (this.options.onNodeEnabled) === 'function') { - this.$element.on('nodeEnabled', this.options.onNodeEnabled); + if (typeof (this._options.onNodeEnabled) === 'function') { + this.$element.on('nodeEnabled', this._options.onNodeEnabled); } - if (typeof (this.options.onNodeExpanded) === 'function') { - this.$element.on('nodeExpanded', this.options.onNodeExpanded); + if (typeof (this._options.onNodeExpanded) === 'function') { + this.$element.on('nodeExpanded', this._options.onNodeExpanded); } - if (typeof (this.options.onNodeSelected) === 'function') { - this.$element.on('nodeSelected', this.options.onNodeSelected); + if (typeof (this._options.onNodeSelected) === 'function') { + this.$element.on('nodeSelected', this._options.onNodeSelected); } - if (typeof (this.options.onNodeUnchecked) === 'function') { - this.$element.on('nodeUnchecked', this.options.onNodeUnchecked); + if (typeof (this._options.onNodeUnchecked) === 'function') { + this.$element.on('nodeUnchecked', this._options.onNodeUnchecked); } - if (typeof (this.options.onNodeUnselected) === 'function') { - this.$element.on('nodeUnselected', this.options.onNodeUnselected); + if (typeof (this._options.onNodeUnselected) === 'function') { + this.$element.on('nodeUnselected', this._options.onNodeUnselected); } - if (typeof (this.options.onSearchComplete) === 'function') { - this.$element.on('searchComplete', this.options.onSearchComplete); + if (typeof (this._options.onSearchComplete) === 'function') { + this.$element.on('searchComplete', this._options.onSearchComplete); } - if (typeof (this.options.onSearchCleared) === 'function') { - this.$element.on('searchCleared', this.options.onSearchCleared); + if (typeof (this._options.onSearchCleared) === 'function') { + this.$element.on('searchCleared', this._options.onSearchCleared); } }; @@ -255,7 +255,7 @@ For performance we also take this opportunity to index nodes in a flattened structure */ - Tree.prototype.setInitialStates = function (node, level) { + Tree.prototype._setInitialStates = function (node, level) { if (!node.nodes) return; level += 1; @@ -265,7 +265,7 @@ $.each(node.nodes, function checkStates(index, node) { // nodeId : unique, incremental identifier - node.nodeId = _this.nodes.length; + node.nodeId = _this._nodes.length; // parentId : transversing up the tree node.parentId = parent.nodeId; @@ -291,7 +291,7 @@ // set expanded state; if not provided based on levels if (!node.state.hasOwnProperty('expanded')) { if (!node.state.disabled && - (level < _this.options.levels) && + (level < _this._options.levels) && (node.nodes && node.nodes.length > 0)) { node.state.expanded = true; } @@ -306,21 +306,21 @@ } // index nodes in a flattened structure for use later - _this.nodes.push(node); + _this._nodes.push(node); // recurse child nodes and transverse the tree if (node.nodes) { - _this.setInitialStates(node, level); + _this._setInitialStates(node, level); } }); }; - Tree.prototype.clickHandler = function (event) { + Tree.prototype._clickHandler = function (event) { - if (!this.options.enableLinks) event.preventDefault(); + if (!this._options.enableLinks) event.preventDefault(); var target = $(event.target); - var node = this.findNode(target); + var node = this.targetNode(target); if (!node || node.state.disabled) return; var classList = target.attr('class') ? target.attr('class').split(' ') : []; @@ -341,10 +341,10 @@ // Looks up the DOM for the closest parent list item to retrieve the // data attribute nodeid, which is used to lookup the node in the flattened structure. - Tree.prototype.findNode = function (target) { + Tree.prototype.targetNode = function (target) { var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); - var node = this.nodes[nodeId]; + var node = this._nodes[nodeId]; if (!node) { console.log('Error: node does not exist'); @@ -371,8 +371,8 @@ // Set element if (node.$el) { node.$el.children('span.expand-icon') - .removeClass(this.options.expandIcon) - .addClass(this.options.collapseIcon); + .removeClass(this._options.expandIcon) + .addClass(this._options.collapseIcon); } // Render child nodes @@ -391,14 +391,13 @@ // Set element if (node.$el) { node.$el.children('span.expand-icon') - .removeClass(this.options.collapseIcon) - .addClass(this.options.expandIcon); + .removeClass(this._options.collapseIcon) + .addClass(this._options.expandIcon); } // Collapse children if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { - console.log('recurse children') this._setExpandedState(node, false, options); }, this)); } @@ -428,8 +427,8 @@ if (state) { // If multiSelect false, unselect previously selected - if (!this.options.multiSelect) { - $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + if (!this._options.multiSelect) { + $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { this._setSelectedState(node, false, options); }, this)); } @@ -441,10 +440,10 @@ if (node.$el) { node.$el.addClass('node-selected'); - if (node.selectedIcon || this.options.selectedIcon) { + if (node.selectedIcon || this._options.selectedIcon) { node.$el.children('span.node-icon') - .removeClass(node.icon || this.options.nodeIcon) - .addClass(node.selectedIcon || this.options.selectedIcon); + .removeClass(node.icon || this._options.nodeIcon) + .addClass(node.selectedIcon || this._options.selectedIcon); } } @@ -462,10 +461,10 @@ if (node.$el) { node.$el.removeClass('node-selected'); - if (node.selectedIcon || this.options.selectedIcon) { + if (node.selectedIcon || this._options.selectedIcon) { node.$el.children('span.node-icon') - .removeClass(node.selectedIcon || this.options.selectedIcon) - .addClass(node.icon || this.options.nodeIcon); + .removeClass(node.selectedIcon || this._options.selectedIcon) + .addClass(node.icon || this._options.nodeIcon); } } @@ -498,8 +497,8 @@ if (node.$el) { node.$el.addClass('node-checked'); node.$el.children('span.check-icon') - .removeClass(this.options.uncheckedIcon) - .addClass(this.options.checkedIcon); + .removeClass(this._options.uncheckedIcon) + .addClass(this._options.checkedIcon); } // Optionally trigger event @@ -516,8 +515,8 @@ if (node.$el) { node.$el.removeClass('node-checked'); node.$el.children('span.check-icon') - .removeClass(this.options.checkedIcon) - .addClass(this.options.uncheckedIcon); + .removeClass(this._options.checkedIcon) + .addClass(this._options.uncheckedIcon); } // Optionally trigger event @@ -570,80 +569,32 @@ } }; - Tree.prototype.render = function () { + Tree.prototype._render = function () { - console.log('RENDER'); - - if (!this.initialized) { + if (!this._initialized) { // Setup first time only components - this.$wrapper = $(this.template.tree); + this.$wrapper = $(this._template.tree); this.$element.empty() .addClass(pluginName) .append(this.$wrapper); - this.injectStyle(); + this._injectStyle(); - this.initialized = true; + this._initialized = true; } - if (!this.tree) return; + if (!this._tree) return; - $.each(this.tree, $.proxy(function addRootNodes(id, node) { + $.each(this._tree, $.proxy(function addRootNodes(id, node) { node.level = 1; this._renderNode(node); }, this)); }; - // Creates a new node element from template and - // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (pEl) { - - var $el = $(this.template.node); - - if (pEl) { - console.log('insert - ' + pEl.text()); - this.$wrapper.children().eq(pEl.index()).after($el); - } - else { - console.log('append'); - this.$wrapper.append($el); - } - - return $el; - }; - - Tree.prototype._collapseNode = function (node) { - if (!node.nodes) return; - - console.log('collapseNode - ' + node.text); - $.each(node.nodes, $.proxy(function (index, node) { - this._collapseNode(node); - if (node.$el) { - node.$el.remove(); - node.$el = null; - } - }, this)); - }; - - Tree.prototype._expandNode = function (node) { - if (!node.nodes) return; - - console.log('expandNode - ' + node.text); - var $pEl = node.$el; - $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { - console.log('expandNode child ' + node.text + ' > ' + childNode.text); - childNode.level = node.level + 1; - this._renderNode(childNode, $pEl); - // $pEl = childNode.$el; - }, this)); - }; - Tree.prototype._renderNode = function (node, pEl) { - console.log('renderNode - ' + node.text); if (!node) return; - // console.log(node); if (!node.$el) { // New node, needs a new element @@ -651,56 +602,45 @@ // One time setup node.$el - .addClass('node-' + this.elementId) + .addClass('node-' + this._elementId) .attr('data-nodeid', node.nodeId); } else { - // TODO Don't blanket empty, eval each action node.$el.empty(); } - // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { - node.$el.append(this.template.indent); - } - - // Add expand, collapse or empty spacer icons - var classList = []; - if (node.nodes) { - classList.push('expand-icon'); - } - else { - classList.push(this.options.emptyIcon); + node.$el.append(this._template.indent); } + // Add expand / collapse or empty spacer icons node.$el - .append($(this.template.icon) - .addClass(classList.join(' ')) + .append($(this._template.icon) + .addClass(node.nodes ? 'expand-icon' : this._options.emptyIcon) ); - // Add node icon - if (this.options.showIcon) { + if (this._options.showIcon) { node.$el - .append($(this.template.icon) + .append($(this._template.icon) .addClass('node-icon') - .addClass(node.icon || this.options.nodeIcon) + .addClass(node.icon || this._options.nodeIcon) ); } // Add checkable icon - if (this.options.showCheckbox) { + if (this._options.showCheckbox) { node.$el - .append($(this.template.icon) + .append($(this._template.icon) .addClass('check-icon') ); } // Add text - if (this.options.enableLinks) { + if (this._options.enableLinks) { node.$el - .append($(this.template.link) + .append($(this._template.link) .attr('href', node.href) .append(node.text) ); @@ -711,10 +651,10 @@ } // Add tags as badges - if (this.options.showTags && node.tags) { + if (this._options.showTags && node.tags) { $.each(node.tags, $.proxy(function addTag(id, tag) { node.$el - .append($(this.template.badge) + .append($(this._template.badge) .append(tag) ); }, this)); @@ -731,74 +671,115 @@ this._setDisabledState(node, node.state.disabled); }; + // Creates a new node element from template and + // ensures the template is inserted at the correct position + Tree.prototype._newNodeEl = function (pEl) { + + var $el = $(this._template.node); + + if (pEl) { + this.$wrapper.children() + .eq(pEl.index()).after($el); + } + else { + this.$wrapper.append($el); + } + + return $el; + }; + + // Collapse node, removing it's immediate children + Tree.prototype._collapseNode = function (node) { + if (!node.nodes) return; + + $.each(node.nodes, $.proxy(function (index, node) { + this._collapseNode(node); + if (node.$el) { + node.$el.remove(); + node.$el = null; + } + }, this)); + }; + + // Expand node, rendering it's immediate children + Tree.prototype._expandNode = function (node) { + if (!node.nodes) return; + + var $pEl = node.$el; + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, $pEl); + }, this)); + }; + // Add inline style into head - Tree.prototype.injectStyle = function () { + Tree.prototype._injectStyle = function () { - if (this.options.injectStyle && !document.getElementById(this.styleId)) { - $('').appendTo('head'); + if (this._options.injectStyle && !document.getElementById(this._styleId)) { + $('').appendTo('head'); } }; // Construct trees style based on user options - Tree.prototype.buildStyle = function () { + Tree.prototype._buildStyle = function () { - var style = '.node-' + this.elementId + '{'; + var style = '.node-' + this._elementId + '{'; // Basic bootstrap style overrides - if (this.options.color) { - style += 'color:' + this.options.color + ';'; + if (this._options.color) { + style += 'color:' + this._options.color + ';'; } - if (this.options.backColor) { - style += 'background-color:' + this.options.backColor + ';'; + if (this._options.backColor) { + style += 'background-color:' + this._options.backColor + ';'; } - if (!this.options.showBorder) { + if (!this._options.showBorder) { style += 'border:none;'; } - else if (this.options.borderColor) { - style += 'border:1px solid ' + this.options.borderColor + ';'; + else if (this._options.borderColor) { + style += 'border:1px solid ' + this._options.borderColor + ';'; } style += '}'; - if (this.options.onhoverColor) { - style += '.node-' + this.elementId + ':not(.node-disabled):hover{' + - 'background-color:' + this.options.onhoverColor + ';' + + if (this._options.onhoverColor) { + style += '.node-' + this._elementId + ':not(.node-disabled):hover{' + + 'background-color:' + this._options.onhoverColor + ';' + '}'; } // Style search results - if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { + if (this._options.highlightSearchResults && (this._options.searchResultColor || this._options.searchResultBackColor)) { var innerStyle = '' - if (this.options.searchResultColor) { - innerStyle += 'color:' + this.options.searchResultColor + ';'; + if (this._options.searchResultColor) { + innerStyle += 'color:' + this._options.searchResultColor + ';'; } - if (this.options.searchResultBackColor) { - innerStyle += 'background-color:' + this.options.searchResultBackColor + ';'; + if (this._options.searchResultBackColor) { + innerStyle += 'background-color:' + this._options.searchResultBackColor + ';'; } - style += '.node-' + this.elementId + '.node-result{' + innerStyle + '}'; - style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-result{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-result:hover{' + innerStyle + '}'; } // Style selected nodes - if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { + if (this._options.highlightSelected && (this._options.selectedColor || this._options.selectedBackColor)) { var innerStyle = '' - if (this.options.selectedColor) { - innerStyle += 'color:' + this.options.selectedColor + ';'; + if (this._options.selectedColor) { + innerStyle += 'color:' + this._options.selectedColor + ';'; } - if (this.options.selectedBackColor) { - innerStyle += 'background-color:' + this.options.selectedBackColor + ';'; + if (this._options.selectedBackColor) { + innerStyle += 'background-color:' + this._options.selectedBackColor + ';'; } - style += '.node-' + this.elementId + '.node-selected{' + innerStyle + '}'; - style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-selected{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-selected:hover{' + innerStyle + '}'; } // Node level style overrides - $.each(this.nodes, $.proxy(function (index, node) { + $.each(this._nodes, $.proxy(function (index, node) { if (node.color || node.backColor) { var innerStyle = ''; if (node.color) { @@ -807,14 +788,14 @@ if (node.backColor) { innerStyle += 'background-color:' + node.backColor + ';'; } - style += '.node-' + this.elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + style += '.node-' + this._elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; } }, this)); - return this.css + style; + return this._css + style; }; - Tree.prototype.template = { + Tree.prototype._template = { tree: '
                                                              ', node: '
                                                            • ', indent: '', @@ -823,7 +804,7 @@ badge: '' }; - Tree.prototype.css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' + Tree.prototype._css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' /** @@ -832,7 +813,7 @@ @return {Object} node - Matching node */ Tree.prototype.getNode = function (nodeId) { - return this.nodes[nodeId]; + return this._nodes[nodeId]; }; /** @@ -841,8 +822,8 @@ @returns {Object} node - The parent node */ Tree.prototype.getParent = function (identifier) { - var node = this.identifyNode(identifier); - return this.nodes[node.parentId]; + var node = this._identifyNode(identifier); + return this._nodes[node.parentId]; }; /** @@ -851,9 +832,9 @@ @returns {Array} nodes - Sibling nodes */ Tree.prototype.getSiblings = function (identifier) { - var node = this.identifyNode(identifier); + var node = this._identifyNode(identifier); var parent = this.getParent(node); - var nodes = parent ? parent.nodes : this.tree; + var nodes = parent ? parent.nodes : this._tree; return nodes.filter(function (obj) { return obj.nodeId !== node.nodeId; }); @@ -864,7 +845,7 @@ @returns {Array} nodes - Selected nodes */ Tree.prototype.getSelected = function () { - return this.findNodes('true', 'g', 'state.selected'); + return this._findNodes('true', 'g', 'state.selected'); }; /** @@ -872,7 +853,7 @@ @returns {Array} nodes - Unselected nodes */ Tree.prototype.getUnselected = function () { - return this.findNodes('false', 'g', 'state.selected'); + return this._findNodes('false', 'g', 'state.selected'); }; /** @@ -880,7 +861,7 @@ @returns {Array} nodes - Expanded nodes */ Tree.prototype.getExpanded = function () { - return this.findNodes('true', 'g', 'state.expanded'); + return this._findNodes('true', 'g', 'state.expanded'); }; /** @@ -888,7 +869,7 @@ @returns {Array} nodes - Collapsed nodes */ Tree.prototype.getCollapsed = function () { - return this.findNodes('false', 'g', 'state.expanded'); + return this._findNodes('false', 'g', 'state.expanded'); }; /** @@ -896,7 +877,7 @@ @returns {Array} nodes - Checked nodes */ Tree.prototype.getChecked = function () { - return this.findNodes('true', 'g', 'state.checked'); + return this._findNodes('true', 'g', 'state.checked'); }; /** @@ -904,7 +885,7 @@ @returns {Array} nodes - Unchecked nodes */ Tree.prototype.getUnchecked = function () { - return this.findNodes('false', 'g', 'state.checked'); + return this._findNodes('false', 'g', 'state.checked'); }; /** @@ -912,7 +893,7 @@ @returns {Array} nodes - Disabled nodes */ Tree.prototype.getDisabled = function () { - return this.findNodes('true', 'g', 'state.disabled'); + return this._findNodes('true', 'g', 'state.disabled'); }; /** @@ -920,7 +901,7 @@ @returns {Array} nodes - Enabled nodes */ Tree.prototype.getEnabled = function () { - return this.findNodes('false', 'g', 'state.disabled'); + return this._findNodes('false', 'g', 'state.disabled'); }; @@ -930,7 +911,7 @@ @param {optional Object} options */ Tree.prototype.selectNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setSelectedState(node, true, options); }, this)); }; @@ -941,7 +922,7 @@ @param {optional Object} options */ Tree.prototype.unselectNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setSelectedState(node, false, options); }, this)); }; @@ -952,7 +933,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleSelectedState(node, options); }, this)); }; @@ -965,7 +946,7 @@ Tree.prototype.collapseAll = function (options) { options = $.extend({}, _default.options, options); options.levels = options.levels || 999; - this.collapseNode(this.tree, options); + this.collapseNode(this._tree, options); }; /** @@ -974,7 +955,7 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setExpandedState(node, false, options); }, this)); }; @@ -986,7 +967,7 @@ Tree.prototype.expandAll = function (options) { options = $.extend({}, _default.options, options); options.levels = options.levels || 999; - this.expandNode(this.tree, options); + this.expandNode(this._tree, options); }; /** @@ -995,7 +976,7 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); @@ -1005,7 +986,6 @@ Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { - console.log('test - ' + node.text); this._setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); @@ -1019,7 +999,7 @@ @param {optional Object} options */ Tree.prototype.revealNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { var parentNode = node; var tmpNode; while (tmpNode = this.getParent(parentNode)) { @@ -1035,7 +1015,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleExpandedState(node, options); }, this)); }; @@ -1046,8 +1026,8 @@ @param {optional Object} options */ Tree.prototype.checkAll = function (options) { - var identifiers = this.findNodes('false', 'g', 'state.checked'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('false', 'g', 'state.checked'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, true, options); }, this)); }; @@ -1058,7 +1038,7 @@ @param {optional Object} options */ Tree.prototype.checkNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, true, options); }, this)); }; @@ -1068,8 +1048,8 @@ @param {optional Object} options */ Tree.prototype.uncheckAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.checked'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('true', 'g', 'state.checked'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, false, options); }, this)); }; @@ -1080,7 +1060,7 @@ @param {optional Object} options */ Tree.prototype.uncheckNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, false, options); }, this)); }; @@ -1091,7 +1071,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleCheckedState(node, options); }, this)); }; @@ -1102,8 +1082,8 @@ @param {optional Object} options */ Tree.prototype.disableAll = function (options) { - var identifiers = this.findNodes('false', 'g', 'state.disabled'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('false', 'g', 'state.disabled'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, true, options); }, this)); }; @@ -1114,7 +1094,7 @@ @param {optional Object} options */ Tree.prototype.disableNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, true, options); }, this)); }; @@ -1124,8 +1104,8 @@ @param {optional Object} options */ Tree.prototype.enableAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.disabled'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('true', 'g', 'state.disabled'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, false, options); }, this)); }; @@ -1136,7 +1116,7 @@ @param {optional Object} options */ Tree.prototype.enableNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, false, options); }, this)); }; @@ -1147,7 +1127,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, !node.state.disabled, options); }, this)); }; @@ -1156,7 +1136,7 @@ /** Common code for processing multiple identifiers */ - Tree.prototype.forEachIdentifier = function (identifiers, options, callback) { + Tree.prototype._forEachIdentifier = function (identifiers, options, callback) { options = $.extend({}, _default.options, options); @@ -1165,16 +1145,16 @@ } $.each(identifiers, $.proxy(function (index, identifier) { - callback(this.identifyNode(identifier), options); + callback(this._identifyNode(identifier), options); }, this)); }; /* Identifies a node from either a node id or object */ - Tree.prototype.identifyNode = function (identifier) { + Tree.prototype._identifyNode = function (identifier) { return ((typeof identifier) === 'number') ? - this.nodes[identifier] : + this._nodes[identifier] : identifier; }; @@ -1201,7 +1181,7 @@ modifier += 'i'; } - results = this.findNodes(pattern, modifier); + results = this._findNodes(pattern, modifier); // Add searchResult property to all matching nodes // This will be used to apply custom styles @@ -1230,7 +1210,7 @@ options = $.extend({}, { render: true }, options); - var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { + var results = $.each(this._findNodes('true', 'g', 'searchResult'), function (index, node) { node.searchResult = false; node.$el.removeClass('node-result'); }); @@ -1245,14 +1225,14 @@ @param {optional String} attribute - Attribute to compare pattern against @return {Array} nodes - Nodes that match your criteria */ - Tree.prototype.findNodes = function (pattern, modifier, attribute) { + Tree.prototype._findNodes = function (pattern, modifier, attribute) { modifier = modifier || 'g'; attribute = attribute || 'text'; var _this = this; - return $.grep(this.nodes, function (node) { - var val = _this.getNodeValue(node, attribute); + return $.grep(this._nodes, function (node) { + var val = _this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } @@ -1266,12 +1246,12 @@ @param {String} attr - Identifies an object property using dot notation @return {String} value - Matching attributes string representation */ - Tree.prototype.getNodeValue = function (obj, attr) { + Tree.prototype._getNodeValue = function (obj, attr) { var index = attr.indexOf('.'); if (index > 0) { var _obj = obj[attr.substring(0, index)]; var _attr = attr.substring(index + 1, attr.length); - return this.getNodeValue(_obj, _attr); + return this._getNodeValue(_obj, _attr); } else { if (obj.hasOwnProperty(attr)) { diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 536f72e23..cb6675e5b 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -86,19 +86,19 @@ var Tree = function (element, options) { this.$element = $(element); - this.elementId = element.id; - this.styleId = this.elementId + '-style'; + this._elementId = element.id; + this._styleId = this._elementId + '-style'; - this.init(options); + this._init(options); return { // Options (public access) - options: this.options, + options: this._options, // Initialize / destroy methods - init: $.proxy(this.init, this), - remove: $.proxy(this.remove, this), + init: $.proxy(this._init, this), + remove: $.proxy(this._remove, this), // Get methods getNode: $.proxy(this.getNode, this), @@ -146,48 +146,48 @@ }; }; - Tree.prototype.init = function (options) { + Tree.prototype._init = function (options) { - this.tree = []; - this.nodes = []; - this.initialized = false; + this._tree = []; + this._nodes = []; + this._initialized = false; if (options.data) { if (typeof options.data === 'string') { options.data = $.parseJSON(options.data); } - this.tree = $.extend(true, [], options.data); + this._tree = $.extend(true, [], options.data); delete options.data; } - this.options = $.extend({}, _default.settings, options); + this._options = $.extend({}, _default.settings, options); - this.destroy(); - this.subscribeEvents(); - this.setInitialStates({ nodes: this.tree }, 0); - this.render(); + this._destroy(); + this._subscribeEvents(); + this._setInitialStates({ nodes: this._tree }, 0); + this._render(); }; - Tree.prototype.remove = function () { - this.destroy(); + Tree.prototype._remove = function () { + this._destroy(); $.removeData(this, pluginName); - $('#' + this.styleId).remove(); + $('#' + this._styleId).remove(); }; - Tree.prototype.destroy = function () { + Tree.prototype._destroy = function () { - if (!this.initialized) return; + if (!this._initialized) return; this.$wrapper.remove(); this.$wrapper = null; // Switch off events - this.unsubscribeEvents(); + this._unsubscribeEvents(); - // Reset this.initialized flag - this.initialized = false; + // Reset this._initialized flag + this._initialized = false; }; - Tree.prototype.unsubscribeEvents = function () { + Tree.prototype._unsubscribeEvents = function () { this.$element.off('click'); this.$element.off('nodeChecked'); @@ -202,50 +202,50 @@ this.$element.off('searchCleared'); }; - Tree.prototype.subscribeEvents = function () { + Tree.prototype._subscribeEvents = function () { - this.unsubscribeEvents(); + this._unsubscribeEvents(); - this.$element.on('click', $.proxy(this.clickHandler, this)); + this.$element.on('click', $.proxy(this._clickHandler, this)); - if (typeof (this.options.onNodeChecked) === 'function') { - this.$element.on('nodeChecked', this.options.onNodeChecked); + if (typeof (this._options.onNodeChecked) === 'function') { + this.$element.on('nodeChecked', this._options.onNodeChecked); } - if (typeof (this.options.onNodeCollapsed) === 'function') { - this.$element.on('nodeCollapsed', this.options.onNodeCollapsed); + if (typeof (this._options.onNodeCollapsed) === 'function') { + this.$element.on('nodeCollapsed', this._options.onNodeCollapsed); } - if (typeof (this.options.onNodeDisabled) === 'function') { - this.$element.on('nodeDisabled', this.options.onNodeDisabled); + if (typeof (this._options.onNodeDisabled) === 'function') { + this.$element.on('nodeDisabled', this._options.onNodeDisabled); } - if (typeof (this.options.onNodeEnabled) === 'function') { - this.$element.on('nodeEnabled', this.options.onNodeEnabled); + if (typeof (this._options.onNodeEnabled) === 'function') { + this.$element.on('nodeEnabled', this._options.onNodeEnabled); } - if (typeof (this.options.onNodeExpanded) === 'function') { - this.$element.on('nodeExpanded', this.options.onNodeExpanded); + if (typeof (this._options.onNodeExpanded) === 'function') { + this.$element.on('nodeExpanded', this._options.onNodeExpanded); } - if (typeof (this.options.onNodeSelected) === 'function') { - this.$element.on('nodeSelected', this.options.onNodeSelected); + if (typeof (this._options.onNodeSelected) === 'function') { + this.$element.on('nodeSelected', this._options.onNodeSelected); } - if (typeof (this.options.onNodeUnchecked) === 'function') { - this.$element.on('nodeUnchecked', this.options.onNodeUnchecked); + if (typeof (this._options.onNodeUnchecked) === 'function') { + this.$element.on('nodeUnchecked', this._options.onNodeUnchecked); } - if (typeof (this.options.onNodeUnselected) === 'function') { - this.$element.on('nodeUnselected', this.options.onNodeUnselected); + if (typeof (this._options.onNodeUnselected) === 'function') { + this.$element.on('nodeUnselected', this._options.onNodeUnselected); } - if (typeof (this.options.onSearchComplete) === 'function') { - this.$element.on('searchComplete', this.options.onSearchComplete); + if (typeof (this._options.onSearchComplete) === 'function') { + this.$element.on('searchComplete', this._options.onSearchComplete); } - if (typeof (this.options.onSearchCleared) === 'function') { - this.$element.on('searchCleared', this.options.onSearchCleared); + if (typeof (this._options.onSearchCleared) === 'function') { + this.$element.on('searchCleared', this._options.onSearchCleared); } }; @@ -255,7 +255,7 @@ For performance we also take this opportunity to index nodes in a flattened structure */ - Tree.prototype.setInitialStates = function (node, level) { + Tree.prototype._setInitialStates = function (node, level) { if (!node.nodes) return; level += 1; @@ -265,7 +265,7 @@ $.each(node.nodes, function checkStates(index, node) { // nodeId : unique, incremental identifier - node.nodeId = _this.nodes.length; + node.nodeId = _this._nodes.length; // parentId : transversing up the tree node.parentId = parent.nodeId; @@ -291,7 +291,7 @@ // set expanded state; if not provided based on levels if (!node.state.hasOwnProperty('expanded')) { if (!node.state.disabled && - (level < _this.options.levels) && + (level < _this._options.levels) && (node.nodes && node.nodes.length > 0)) { node.state.expanded = true; } @@ -306,21 +306,21 @@ } // index nodes in a flattened structure for use later - _this.nodes.push(node); + _this._nodes.push(node); // recurse child nodes and transverse the tree if (node.nodes) { - _this.setInitialStates(node, level); + _this._setInitialStates(node, level); } }); }; - Tree.prototype.clickHandler = function (event) { + Tree.prototype._clickHandler = function (event) { - if (!this.options.enableLinks) event.preventDefault(); + if (!this._options.enableLinks) event.preventDefault(); var target = $(event.target); - var node = this.findNode(target); + var node = this.targetNode(target); if (!node || node.state.disabled) return; var classList = target.attr('class') ? target.attr('class').split(' ') : []; @@ -341,10 +341,10 @@ // Looks up the DOM for the closest parent list item to retrieve the // data attribute nodeid, which is used to lookup the node in the flattened structure. - Tree.prototype.findNode = function (target) { + Tree.prototype.targetNode = function (target) { var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); - var node = this.nodes[nodeId]; + var node = this._nodes[nodeId]; if (!node) { console.log('Error: node does not exist'); @@ -371,8 +371,8 @@ // Set element if (node.$el) { node.$el.children('span.expand-icon') - .removeClass(this.options.expandIcon) - .addClass(this.options.collapseIcon); + .removeClass(this._options.expandIcon) + .addClass(this._options.collapseIcon); } // Render child nodes @@ -391,14 +391,13 @@ // Set element if (node.$el) { node.$el.children('span.expand-icon') - .removeClass(this.options.collapseIcon) - .addClass(this.options.expandIcon); + .removeClass(this._options.collapseIcon) + .addClass(this._options.expandIcon); } // Collapse children if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { - console.log('recurse children') this._setExpandedState(node, false, options); }, this)); } @@ -428,8 +427,8 @@ if (state) { // If multiSelect false, unselect previously selected - if (!this.options.multiSelect) { - $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + if (!this._options.multiSelect) { + $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { this._setSelectedState(node, false, options); }, this)); } @@ -441,10 +440,10 @@ if (node.$el) { node.$el.addClass('node-selected'); - if (node.selectedIcon || this.options.selectedIcon) { + if (node.selectedIcon || this._options.selectedIcon) { node.$el.children('span.node-icon') - .removeClass(node.icon || this.options.nodeIcon) - .addClass(node.selectedIcon || this.options.selectedIcon); + .removeClass(node.icon || this._options.nodeIcon) + .addClass(node.selectedIcon || this._options.selectedIcon); } } @@ -462,10 +461,10 @@ if (node.$el) { node.$el.removeClass('node-selected'); - if (node.selectedIcon || this.options.selectedIcon) { + if (node.selectedIcon || this._options.selectedIcon) { node.$el.children('span.node-icon') - .removeClass(node.selectedIcon || this.options.selectedIcon) - .addClass(node.icon || this.options.nodeIcon); + .removeClass(node.selectedIcon || this._options.selectedIcon) + .addClass(node.icon || this._options.nodeIcon); } } @@ -498,8 +497,8 @@ if (node.$el) { node.$el.addClass('node-checked'); node.$el.children('span.check-icon') - .removeClass(this.options.uncheckedIcon) - .addClass(this.options.checkedIcon); + .removeClass(this._options.uncheckedIcon) + .addClass(this._options.checkedIcon); } // Optionally trigger event @@ -516,8 +515,8 @@ if (node.$el) { node.$el.removeClass('node-checked'); node.$el.children('span.check-icon') - .removeClass(this.options.checkedIcon) - .addClass(this.options.uncheckedIcon); + .removeClass(this._options.checkedIcon) + .addClass(this._options.uncheckedIcon); } // Optionally trigger event @@ -570,80 +569,32 @@ } }; - Tree.prototype.render = function () { + Tree.prototype._render = function () { - console.log('RENDER'); - - if (!this.initialized) { + if (!this._initialized) { // Setup first time only components - this.$wrapper = $(this.template.tree); + this.$wrapper = $(this._template.tree); this.$element.empty() .addClass(pluginName) .append(this.$wrapper); - this.injectStyle(); + this._injectStyle(); - this.initialized = true; + this._initialized = true; } - if (!this.tree) return; + if (!this._tree) return; - $.each(this.tree, $.proxy(function addRootNodes(id, node) { + $.each(this._tree, $.proxy(function addRootNodes(id, node) { node.level = 1; this._renderNode(node); }, this)); }; - // Creates a new node element from template and - // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (pEl) { - - var $el = $(this.template.node); - - if (pEl) { - console.log('insert - ' + pEl.text()); - this.$wrapper.children().eq(pEl.index()).after($el); - } - else { - console.log('append'); - this.$wrapper.append($el); - } - - return $el; - }; - - Tree.prototype._collapseNode = function (node) { - if (!node.nodes) return; - - console.log('collapseNode - ' + node.text); - $.each(node.nodes, $.proxy(function (index, node) { - this._collapseNode(node); - if (node.$el) { - node.$el.remove(); - node.$el = null; - } - }, this)); - }; - - Tree.prototype._expandNode = function (node) { - if (!node.nodes) return; - - console.log('expandNode - ' + node.text); - var $pEl = node.$el; - $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { - console.log('expandNode child ' + node.text + ' > ' + childNode.text); - childNode.level = node.level + 1; - this._renderNode(childNode, $pEl); - // $pEl = childNode.$el; - }, this)); - }; - Tree.prototype._renderNode = function (node, pEl) { - console.log('renderNode - ' + node.text); if (!node) return; - // console.log(node); if (!node.$el) { // New node, needs a new element @@ -651,56 +602,45 @@ // One time setup node.$el - .addClass('node-' + this.elementId) + .addClass('node-' + this._elementId) .attr('data-nodeid', node.nodeId); } else { - // TODO Don't blanket empty, eval each action node.$el.empty(); } - // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { - node.$el.append(this.template.indent); - } - - // Add expand, collapse or empty spacer icons - var classList = []; - if (node.nodes) { - classList.push('expand-icon'); - } - else { - classList.push(this.options.emptyIcon); + node.$el.append(this._template.indent); } + // Add expand / collapse or empty spacer icons node.$el - .append($(this.template.icon) - .addClass(classList.join(' ')) + .append($(this._template.icon) + .addClass(node.nodes ? 'expand-icon' : this._options.emptyIcon) ); - // Add node icon - if (this.options.showIcon) { + if (this._options.showIcon) { node.$el - .append($(this.template.icon) + .append($(this._template.icon) .addClass('node-icon') - .addClass(node.icon || this.options.nodeIcon) + .addClass(node.icon || this._options.nodeIcon) ); } // Add checkable icon - if (this.options.showCheckbox) { + if (this._options.showCheckbox) { node.$el - .append($(this.template.icon) + .append($(this._template.icon) .addClass('check-icon') ); } // Add text - if (this.options.enableLinks) { + if (this._options.enableLinks) { node.$el - .append($(this.template.link) + .append($(this._template.link) .attr('href', node.href) .append(node.text) ); @@ -711,10 +651,10 @@ } // Add tags as badges - if (this.options.showTags && node.tags) { + if (this._options.showTags && node.tags) { $.each(node.tags, $.proxy(function addTag(id, tag) { node.$el - .append($(this.template.badge) + .append($(this._template.badge) .append(tag) ); }, this)); @@ -731,74 +671,115 @@ this._setDisabledState(node, node.state.disabled); }; + // Creates a new node element from template and + // ensures the template is inserted at the correct position + Tree.prototype._newNodeEl = function (pEl) { + + var $el = $(this._template.node); + + if (pEl) { + this.$wrapper.children() + .eq(pEl.index()).after($el); + } + else { + this.$wrapper.append($el); + } + + return $el; + }; + + // Collapse node, removing it's immediate children + Tree.prototype._collapseNode = function (node) { + if (!node.nodes) return; + + $.each(node.nodes, $.proxy(function (index, node) { + this._collapseNode(node); + if (node.$el) { + node.$el.remove(); + node.$el = null; + } + }, this)); + }; + + // Expand node, rendering it's immediate children + Tree.prototype._expandNode = function (node) { + if (!node.nodes) return; + + var $pEl = node.$el; + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, $pEl); + }, this)); + }; + // Add inline style into head - Tree.prototype.injectStyle = function () { + Tree.prototype._injectStyle = function () { - if (this.options.injectStyle && !document.getElementById(this.styleId)) { - $('').appendTo('head'); + if (this._options.injectStyle && !document.getElementById(this._styleId)) { + $('').appendTo('head'); } }; // Construct trees style based on user options - Tree.prototype.buildStyle = function () { + Tree.prototype._buildStyle = function () { - var style = '.node-' + this.elementId + '{'; + var style = '.node-' + this._elementId + '{'; // Basic bootstrap style overrides - if (this.options.color) { - style += 'color:' + this.options.color + ';'; + if (this._options.color) { + style += 'color:' + this._options.color + ';'; } - if (this.options.backColor) { - style += 'background-color:' + this.options.backColor + ';'; + if (this._options.backColor) { + style += 'background-color:' + this._options.backColor + ';'; } - if (!this.options.showBorder) { + if (!this._options.showBorder) { style += 'border:none;'; } - else if (this.options.borderColor) { - style += 'border:1px solid ' + this.options.borderColor + ';'; + else if (this._options.borderColor) { + style += 'border:1px solid ' + this._options.borderColor + ';'; } style += '}'; - if (this.options.onhoverColor) { - style += '.node-' + this.elementId + ':not(.node-disabled):hover{' + - 'background-color:' + this.options.onhoverColor + ';' + + if (this._options.onhoverColor) { + style += '.node-' + this._elementId + ':not(.node-disabled):hover{' + + 'background-color:' + this._options.onhoverColor + ';' + '}'; } // Style search results - if (this.options.highlightSearchResults && (this.options.searchResultColor || this.options.searchResultBackColor)) { + if (this._options.highlightSearchResults && (this._options.searchResultColor || this._options.searchResultBackColor)) { var innerStyle = '' - if (this.options.searchResultColor) { - innerStyle += 'color:' + this.options.searchResultColor + ';'; + if (this._options.searchResultColor) { + innerStyle += 'color:' + this._options.searchResultColor + ';'; } - if (this.options.searchResultBackColor) { - innerStyle += 'background-color:' + this.options.searchResultBackColor + ';'; + if (this._options.searchResultBackColor) { + innerStyle += 'background-color:' + this._options.searchResultBackColor + ';'; } - style += '.node-' + this.elementId + '.node-result{' + innerStyle + '}'; - style += '.node-' + this.elementId + '.node-result:hover{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-result{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-result:hover{' + innerStyle + '}'; } // Style selected nodes - if (this.options.highlightSelected && (this.options.selectedColor || this.options.selectedBackColor)) { + if (this._options.highlightSelected && (this._options.selectedColor || this._options.selectedBackColor)) { var innerStyle = '' - if (this.options.selectedColor) { - innerStyle += 'color:' + this.options.selectedColor + ';'; + if (this._options.selectedColor) { + innerStyle += 'color:' + this._options.selectedColor + ';'; } - if (this.options.selectedBackColor) { - innerStyle += 'background-color:' + this.options.selectedBackColor + ';'; + if (this._options.selectedBackColor) { + innerStyle += 'background-color:' + this._options.selectedBackColor + ';'; } - style += '.node-' + this.elementId + '.node-selected{' + innerStyle + '}'; - style += '.node-' + this.elementId + '.node-selected:hover{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-selected{' + innerStyle + '}'; + style += '.node-' + this._elementId + '.node-selected:hover{' + innerStyle + '}'; } // Node level style overrides - $.each(this.nodes, $.proxy(function (index, node) { + $.each(this._nodes, $.proxy(function (index, node) { if (node.color || node.backColor) { var innerStyle = ''; if (node.color) { @@ -807,14 +788,14 @@ if (node.backColor) { innerStyle += 'background-color:' + node.backColor + ';'; } - style += '.node-' + this.elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + style += '.node-' + this._elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; } }, this)); - return this.css + style; + return this._css + style; }; - Tree.prototype.template = { + Tree.prototype._template = { tree: '
                                                                ', node: '
                                                              • ', indent: '', @@ -823,7 +804,7 @@ badge: '' }; - Tree.prototype.css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' + Tree.prototype._css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' /** @@ -832,7 +813,7 @@ @return {Object} node - Matching node */ Tree.prototype.getNode = function (nodeId) { - return this.nodes[nodeId]; + return this._nodes[nodeId]; }; /** @@ -841,8 +822,8 @@ @returns {Object} node - The parent node */ Tree.prototype.getParent = function (identifier) { - var node = this.identifyNode(identifier); - return this.nodes[node.parentId]; + var node = this._identifyNode(identifier); + return this._nodes[node.parentId]; }; /** @@ -851,9 +832,9 @@ @returns {Array} nodes - Sibling nodes */ Tree.prototype.getSiblings = function (identifier) { - var node = this.identifyNode(identifier); + var node = this._identifyNode(identifier); var parent = this.getParent(node); - var nodes = parent ? parent.nodes : this.tree; + var nodes = parent ? parent.nodes : this._tree; return nodes.filter(function (obj) { return obj.nodeId !== node.nodeId; }); @@ -864,7 +845,7 @@ @returns {Array} nodes - Selected nodes */ Tree.prototype.getSelected = function () { - return this.findNodes('true', 'g', 'state.selected'); + return this._findNodes('true', 'g', 'state.selected'); }; /** @@ -872,7 +853,7 @@ @returns {Array} nodes - Unselected nodes */ Tree.prototype.getUnselected = function () { - return this.findNodes('false', 'g', 'state.selected'); + return this._findNodes('false', 'g', 'state.selected'); }; /** @@ -880,7 +861,7 @@ @returns {Array} nodes - Expanded nodes */ Tree.prototype.getExpanded = function () { - return this.findNodes('true', 'g', 'state.expanded'); + return this._findNodes('true', 'g', 'state.expanded'); }; /** @@ -888,7 +869,7 @@ @returns {Array} nodes - Collapsed nodes */ Tree.prototype.getCollapsed = function () { - return this.findNodes('false', 'g', 'state.expanded'); + return this._findNodes('false', 'g', 'state.expanded'); }; /** @@ -896,7 +877,7 @@ @returns {Array} nodes - Checked nodes */ Tree.prototype.getChecked = function () { - return this.findNodes('true', 'g', 'state.checked'); + return this._findNodes('true', 'g', 'state.checked'); }; /** @@ -904,7 +885,7 @@ @returns {Array} nodes - Unchecked nodes */ Tree.prototype.getUnchecked = function () { - return this.findNodes('false', 'g', 'state.checked'); + return this._findNodes('false', 'g', 'state.checked'); }; /** @@ -912,7 +893,7 @@ @returns {Array} nodes - Disabled nodes */ Tree.prototype.getDisabled = function () { - return this.findNodes('true', 'g', 'state.disabled'); + return this._findNodes('true', 'g', 'state.disabled'); }; /** @@ -920,7 +901,7 @@ @returns {Array} nodes - Enabled nodes */ Tree.prototype.getEnabled = function () { - return this.findNodes('false', 'g', 'state.disabled'); + return this._findNodes('false', 'g', 'state.disabled'); }; @@ -930,7 +911,7 @@ @param {optional Object} options */ Tree.prototype.selectNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setSelectedState(node, true, options); }, this)); }; @@ -941,7 +922,7 @@ @param {optional Object} options */ Tree.prototype.unselectNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setSelectedState(node, false, options); }, this)); }; @@ -952,7 +933,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleSelectedState(node, options); }, this)); }; @@ -965,7 +946,7 @@ Tree.prototype.collapseAll = function (options) { options = $.extend({}, _default.options, options); options.levels = options.levels || 999; - this.collapseNode(this.tree, options); + this.collapseNode(this._tree, options); }; /** @@ -974,7 +955,7 @@ @param {optional Object} options */ Tree.prototype.collapseNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setExpandedState(node, false, options); }, this)); }; @@ -986,7 +967,7 @@ Tree.prototype.expandAll = function (options) { options = $.extend({}, _default.options, options); options.levels = options.levels || 999; - this.expandNode(this.tree, options); + this.expandNode(this._tree, options); }; /** @@ -995,7 +976,7 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setExpandedState(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); @@ -1005,7 +986,6 @@ Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { - console.log('test - ' + node.text); this._setExpandedState(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); @@ -1019,7 +999,7 @@ @param {optional Object} options */ Tree.prototype.revealNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { var parentNode = node; var tmpNode; while (tmpNode = this.getParent(parentNode)) { @@ -1035,7 +1015,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleExpandedState(node, options); }, this)); }; @@ -1046,8 +1026,8 @@ @param {optional Object} options */ Tree.prototype.checkAll = function (options) { - var identifiers = this.findNodes('false', 'g', 'state.checked'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('false', 'g', 'state.checked'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, true, options); }, this)); }; @@ -1058,7 +1038,7 @@ @param {optional Object} options */ Tree.prototype.checkNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, true, options); }, this)); }; @@ -1068,8 +1048,8 @@ @param {optional Object} options */ Tree.prototype.uncheckAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.checked'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('true', 'g', 'state.checked'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, false, options); }, this)); }; @@ -1080,7 +1060,7 @@ @param {optional Object} options */ Tree.prototype.uncheckNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setCheckedState(node, false, options); }, this)); }; @@ -1091,7 +1071,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._toggleCheckedState(node, options); }, this)); }; @@ -1102,8 +1082,8 @@ @param {optional Object} options */ Tree.prototype.disableAll = function (options) { - var identifiers = this.findNodes('false', 'g', 'state.disabled'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('false', 'g', 'state.disabled'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, true, options); }, this)); }; @@ -1114,7 +1094,7 @@ @param {optional Object} options */ Tree.prototype.disableNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, true, options); }, this)); }; @@ -1124,8 +1104,8 @@ @param {optional Object} options */ Tree.prototype.enableAll = function (options) { - var identifiers = this.findNodes('true', 'g', 'state.disabled'); - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var identifiers = this._findNodes('true', 'g', 'state.disabled'); + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, false, options); }, this)); }; @@ -1136,7 +1116,7 @@ @param {optional Object} options */ Tree.prototype.enableNode = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, false, options); }, this)); }; @@ -1147,7 +1127,7 @@ @param {optional Object} options */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { - this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { this._setDisabledState(node, !node.state.disabled, options); }, this)); }; @@ -1156,7 +1136,7 @@ /** Common code for processing multiple identifiers */ - Tree.prototype.forEachIdentifier = function (identifiers, options, callback) { + Tree.prototype._forEachIdentifier = function (identifiers, options, callback) { options = $.extend({}, _default.options, options); @@ -1165,16 +1145,16 @@ } $.each(identifiers, $.proxy(function (index, identifier) { - callback(this.identifyNode(identifier), options); + callback(this._identifyNode(identifier), options); }, this)); }; /* Identifies a node from either a node id or object */ - Tree.prototype.identifyNode = function (identifier) { + Tree.prototype._identifyNode = function (identifier) { return ((typeof identifier) === 'number') ? - this.nodes[identifier] : + this._nodes[identifier] : identifier; }; @@ -1201,7 +1181,7 @@ modifier += 'i'; } - results = this.findNodes(pattern, modifier); + results = this._findNodes(pattern, modifier); // Add searchResult property to all matching nodes // This will be used to apply custom styles @@ -1230,7 +1210,7 @@ options = $.extend({}, { render: true }, options); - var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { + var results = $.each(this._findNodes('true', 'g', 'searchResult'), function (index, node) { node.searchResult = false; node.$el.removeClass('node-result'); }); @@ -1245,14 +1225,14 @@ @param {optional String} attribute - Attribute to compare pattern against @return {Array} nodes - Nodes that match your criteria */ - Tree.prototype.findNodes = function (pattern, modifier, attribute) { + Tree.prototype._findNodes = function (pattern, modifier, attribute) { modifier = modifier || 'g'; attribute = attribute || 'text'; var _this = this; - return $.grep(this.nodes, function (node) { - var val = _this.getNodeValue(node, attribute); + return $.grep(this._nodes, function (node) { + var val = _this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } @@ -1266,12 +1246,12 @@ @param {String} attr - Identifies an object property using dot notation @return {String} value - Matching attributes string representation */ - Tree.prototype.getNodeValue = function (obj, attr) { + Tree.prototype._getNodeValue = function (obj, attr) { var index = attr.indexOf('.'); if (index > 0) { var _obj = obj[attr.substring(0, index)]; var _attr = attr.substring(index + 1, attr.length); - return this.getNodeValue(_obj, _attr); + return this._getNodeValue(_obj, _attr); } else { if (obj.hasOwnProperty(attr)) { From e3428e2b45a036ab2e255e2653c01910d27e34f4 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 27 Jun 2015 10:24:53 +0100 Subject: [PATCH 12/52] Renamed state methods to better reflect their new purpose --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 82 ++++++++++++++++----------------- src/js/bootstrap-treeview.js | 82 ++++++++++++++++----------------- tests/lib/bootstrap-treeview.js | 82 ++++++++++++++++----------------- 4 files changed, 124 insertions(+), 124 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 77159732b..7e72f6273 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpandedState(d,f.options):-1!==e.indexOf("check-icon")?this._toggleCheckedState(d,f.options):d.selectable?this._toggleSelectedState(d,f.options):this._toggleExpandedState(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpandedState=function(a,b){a&&this._setExpandedState(a,!a.state.expanded,b)},g.prototype._setExpandedState=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpandedState(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelectedState=function(a,b){return a?(this._setSelectedState(a,!a.state.selected,b),this):void 0},g.prototype._setSelectedState=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelectedState(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleCheckedState=function(a,b){a&&this._setCheckedState(a,!a.state.checked,b)},g.prototype._setCheckedState=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabledState=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelectedState(b,!1,d),this._setCheckedState(b,!1,d),this._setExpandedState(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                  ',node:'
                                                                • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelectedState(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelectedState(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpandedState(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpandedState(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpandedState(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpandedState(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setCheckedState(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleCheckedState(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabledState(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this._findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpanded(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                    ',node:'
                                                                  • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this._findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index cb6675e5b..ec17d9894 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -325,16 +325,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - this._toggleExpandedState(node, _default.options); + this._toggleExpanded(node, _default.options); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleCheckedState(node, _default.options); + this._toggleChecked(node, _default.options); } else { if (node.selectable) { - this._toggleSelectedState(node, _default.options); + this._toggleSelected(node, _default.options); } else { - this._toggleExpandedState(node, _default.options); + this._toggleExpanded(node, _default.options); } } }; @@ -352,12 +352,12 @@ return node; }; - Tree.prototype._toggleExpandedState = function (node, options) { + Tree.prototype._toggleExpanded = function (node, options) { if (!node) return; - this._setExpandedState(node, !node.state.expanded, options); + this._setExpanded(node, !node.state.expanded, options); }; - Tree.prototype._setExpandedState = function (node, state, options) { + Tree.prototype._setExpanded = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -398,7 +398,7 @@ // Collapse children if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { - this._setExpandedState(node, false, options); + this._setExpanded(node, false, options); }, this)); } @@ -412,13 +412,13 @@ } }; - Tree.prototype._toggleSelectedState = function (node, options) { + Tree.prototype._toggleSelected = function (node, options) { if (!node) return; - this._setSelectedState(node, !node.state.selected, options); + this._setSelected(node, !node.state.selected, options); return this; }; - Tree.prototype._setSelectedState = function (node, state, options) { + Tree.prototype._setSelected = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -429,7 +429,7 @@ // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this._setSelectedState(node, false, options); + this._setSelected(node, false, options); }, this)); } @@ -477,12 +477,12 @@ return this; }; - Tree.prototype._toggleCheckedState = function (node, options) { + Tree.prototype._toggleChecked = function (node, options) { if (!node) return; - this._setCheckedState(node, !node.state.checked, options); + this._setChecked(node, !node.state.checked, options); }; - Tree.prototype._setCheckedState = function (node, state, options) { + Tree.prototype._setChecked = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -526,7 +526,7 @@ } }; - Tree.prototype._setDisabledState = function (node, state, options) { + Tree.prototype._setDisabled = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -538,9 +538,9 @@ node.state.disabled = true; // Disable all other states - this._setSelectedState(node, false, options); - this._setCheckedState(node, false, options); - this._setExpandedState(node, false, options); + this._setSelected(node, false, options); + this._setChecked(node, false, options); + this._setExpanded(node, false, options); // Set element if (node.$el) { @@ -661,14 +661,14 @@ } // Set various node states - this._setSelectedState(node, node.state.selected); - this._setCheckedState(node, node.state.checked); + this._setSelected(node, node.state.selected); + this._setChecked(node, node.state.checked); // Set expanded state also triggers recursive tree build - this._setExpandedState(node, node.state.expanded); + this._setExpanded(node, node.state.expanded); // Finally disabled, which will override any of previous states when true - this._setDisabledState(node, node.state.disabled); + this._setDisabled(node, node.state.disabled); }; // Creates a new node element from template and @@ -912,7 +912,7 @@ */ Tree.prototype.selectNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setSelectedState(node, true, options); + this._setSelected(node, true, options); }, this)); }; @@ -923,7 +923,7 @@ */ Tree.prototype.unselectNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setSelectedState(node, false, options); + this._setSelected(node, false, options); }, this)); }; @@ -934,7 +934,7 @@ */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleSelectedState(node, options); + this._toggleSelected(node, options); }, this)); }; @@ -956,7 +956,7 @@ */ Tree.prototype.collapseNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setExpandedState(node, false, options); + this._setExpanded(node, false, options); }, this)); }; @@ -977,7 +977,7 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setExpandedState(node, true, options); + this._setExpanded(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } @@ -986,7 +986,7 @@ Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { - this._setExpandedState(node, (level > 0) ? true : false, options); + this._setExpanded(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); } @@ -1004,7 +1004,7 @@ var tmpNode; while (tmpNode = this.getParent(parentNode)) { parentNode = tmpNode; - this._setExpandedState(parentNode, true, options); + this._setExpanded(parentNode, true, options); }; }, this)); }; @@ -1016,7 +1016,7 @@ */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleExpandedState(node, options); + this._toggleExpanded(node, options); }, this)); }; @@ -1028,7 +1028,7 @@ Tree.prototype.checkAll = function (options) { var identifiers = this._findNodes('false', 'g', 'state.checked'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, true, options); + this._setChecked(node, true, options); }, this)); }; @@ -1039,7 +1039,7 @@ */ Tree.prototype.checkNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, true, options); + this._setChecked(node, true, options); }, this)); }; @@ -1050,7 +1050,7 @@ Tree.prototype.uncheckAll = function (options) { var identifiers = this._findNodes('true', 'g', 'state.checked'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, false, options); + this._setChecked(node, false, options); }, this)); }; @@ -1061,7 +1061,7 @@ */ Tree.prototype.uncheckNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, false, options); + this._setChecked(node, false, options); }, this)); }; @@ -1072,7 +1072,7 @@ */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleCheckedState(node, options); + this._toggleChecked(node, options); }, this)); }; @@ -1084,7 +1084,7 @@ Tree.prototype.disableAll = function (options) { var identifiers = this._findNodes('false', 'g', 'state.disabled'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, true, options); + this._setDisabled(node, true, options); }, this)); }; @@ -1095,7 +1095,7 @@ */ Tree.prototype.disableNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, true, options); + this._setDisabled(node, true, options); }, this)); }; @@ -1106,7 +1106,7 @@ Tree.prototype.enableAll = function (options) { var identifiers = this._findNodes('true', 'g', 'state.disabled'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, false, options); + this._setDisabled(node, false, options); }, this)); }; @@ -1117,7 +1117,7 @@ */ Tree.prototype.enableNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, false, options); + this._setDisabled(node, false, options); }, this)); }; @@ -1128,7 +1128,7 @@ */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, !node.state.disabled, options); + this._setDisabled(node, !node.state.disabled, options); }, this)); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index cb6675e5b..ec17d9894 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -325,16 +325,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - this._toggleExpandedState(node, _default.options); + this._toggleExpanded(node, _default.options); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleCheckedState(node, _default.options); + this._toggleChecked(node, _default.options); } else { if (node.selectable) { - this._toggleSelectedState(node, _default.options); + this._toggleSelected(node, _default.options); } else { - this._toggleExpandedState(node, _default.options); + this._toggleExpanded(node, _default.options); } } }; @@ -352,12 +352,12 @@ return node; }; - Tree.prototype._toggleExpandedState = function (node, options) { + Tree.prototype._toggleExpanded = function (node, options) { if (!node) return; - this._setExpandedState(node, !node.state.expanded, options); + this._setExpanded(node, !node.state.expanded, options); }; - Tree.prototype._setExpandedState = function (node, state, options) { + Tree.prototype._setExpanded = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -398,7 +398,7 @@ // Collapse children if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { - this._setExpandedState(node, false, options); + this._setExpanded(node, false, options); }, this)); } @@ -412,13 +412,13 @@ } }; - Tree.prototype._toggleSelectedState = function (node, options) { + Tree.prototype._toggleSelected = function (node, options) { if (!node) return; - this._setSelectedState(node, !node.state.selected, options); + this._setSelected(node, !node.state.selected, options); return this; }; - Tree.prototype._setSelectedState = function (node, state, options) { + Tree.prototype._setSelected = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -429,7 +429,7 @@ // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this._setSelectedState(node, false, options); + this._setSelected(node, false, options); }, this)); } @@ -477,12 +477,12 @@ return this; }; - Tree.prototype._toggleCheckedState = function (node, options) { + Tree.prototype._toggleChecked = function (node, options) { if (!node) return; - this._setCheckedState(node, !node.state.checked, options); + this._setChecked(node, !node.state.checked, options); }; - Tree.prototype._setCheckedState = function (node, state, options) { + Tree.prototype._setChecked = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -526,7 +526,7 @@ } }; - Tree.prototype._setDisabledState = function (node, state, options) { + Tree.prototype._setDisabled = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -538,9 +538,9 @@ node.state.disabled = true; // Disable all other states - this._setSelectedState(node, false, options); - this._setCheckedState(node, false, options); - this._setExpandedState(node, false, options); + this._setSelected(node, false, options); + this._setChecked(node, false, options); + this._setExpanded(node, false, options); // Set element if (node.$el) { @@ -661,14 +661,14 @@ } // Set various node states - this._setSelectedState(node, node.state.selected); - this._setCheckedState(node, node.state.checked); + this._setSelected(node, node.state.selected); + this._setChecked(node, node.state.checked); // Set expanded state also triggers recursive tree build - this._setExpandedState(node, node.state.expanded); + this._setExpanded(node, node.state.expanded); // Finally disabled, which will override any of previous states when true - this._setDisabledState(node, node.state.disabled); + this._setDisabled(node, node.state.disabled); }; // Creates a new node element from template and @@ -912,7 +912,7 @@ */ Tree.prototype.selectNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setSelectedState(node, true, options); + this._setSelected(node, true, options); }, this)); }; @@ -923,7 +923,7 @@ */ Tree.prototype.unselectNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setSelectedState(node, false, options); + this._setSelected(node, false, options); }, this)); }; @@ -934,7 +934,7 @@ */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleSelectedState(node, options); + this._toggleSelected(node, options); }, this)); }; @@ -956,7 +956,7 @@ */ Tree.prototype.collapseNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setExpandedState(node, false, options); + this._setExpanded(node, false, options); }, this)); }; @@ -977,7 +977,7 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setExpandedState(node, true, options); + this._setExpanded(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } @@ -986,7 +986,7 @@ Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { - this._setExpandedState(node, (level > 0) ? true : false, options); + this._setExpanded(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); } @@ -1004,7 +1004,7 @@ var tmpNode; while (tmpNode = this.getParent(parentNode)) { parentNode = tmpNode; - this._setExpandedState(parentNode, true, options); + this._setExpanded(parentNode, true, options); }; }, this)); }; @@ -1016,7 +1016,7 @@ */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleExpandedState(node, options); + this._toggleExpanded(node, options); }, this)); }; @@ -1028,7 +1028,7 @@ Tree.prototype.checkAll = function (options) { var identifiers = this._findNodes('false', 'g', 'state.checked'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, true, options); + this._setChecked(node, true, options); }, this)); }; @@ -1039,7 +1039,7 @@ */ Tree.prototype.checkNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, true, options); + this._setChecked(node, true, options); }, this)); }; @@ -1050,7 +1050,7 @@ Tree.prototype.uncheckAll = function (options) { var identifiers = this._findNodes('true', 'g', 'state.checked'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, false, options); + this._setChecked(node, false, options); }, this)); }; @@ -1061,7 +1061,7 @@ */ Tree.prototype.uncheckNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, false, options); + this._setChecked(node, false, options); }, this)); }; @@ -1072,7 +1072,7 @@ */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleCheckedState(node, options); + this._toggleChecked(node, options); }, this)); }; @@ -1084,7 +1084,7 @@ Tree.prototype.disableAll = function (options) { var identifiers = this._findNodes('false', 'g', 'state.disabled'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, true, options); + this._setDisabled(node, true, options); }, this)); }; @@ -1095,7 +1095,7 @@ */ Tree.prototype.disableNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, true, options); + this._setDisabled(node, true, options); }, this)); }; @@ -1106,7 +1106,7 @@ Tree.prototype.enableAll = function (options) { var identifiers = this._findNodes('true', 'g', 'state.disabled'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, false, options); + this._setDisabled(node, false, options); }, this)); }; @@ -1117,7 +1117,7 @@ */ Tree.prototype.enableNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, false, options); + this._setDisabled(node, false, options); }, this)); }; @@ -1128,7 +1128,7 @@ */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, !node.state.disabled, options); + this._setDisabled(node, !node.state.disabled, options); }, this)); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index cb6675e5b..ec17d9894 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -325,16 +325,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - this._toggleExpandedState(node, _default.options); + this._toggleExpanded(node, _default.options); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleCheckedState(node, _default.options); + this._toggleChecked(node, _default.options); } else { if (node.selectable) { - this._toggleSelectedState(node, _default.options); + this._toggleSelected(node, _default.options); } else { - this._toggleExpandedState(node, _default.options); + this._toggleExpanded(node, _default.options); } } }; @@ -352,12 +352,12 @@ return node; }; - Tree.prototype._toggleExpandedState = function (node, options) { + Tree.prototype._toggleExpanded = function (node, options) { if (!node) return; - this._setExpandedState(node, !node.state.expanded, options); + this._setExpanded(node, !node.state.expanded, options); }; - Tree.prototype._setExpandedState = function (node, state, options) { + Tree.prototype._setExpanded = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -398,7 +398,7 @@ // Collapse children if (node.nodes && options && !options.ignoreChildren) { $.each(node.nodes, $.proxy(function (index, node) { - this._setExpandedState(node, false, options); + this._setExpanded(node, false, options); }, this)); } @@ -412,13 +412,13 @@ } }; - Tree.prototype._toggleSelectedState = function (node, options) { + Tree.prototype._toggleSelected = function (node, options) { if (!node) return; - this._setSelectedState(node, !node.state.selected, options); + this._setSelected(node, !node.state.selected, options); return this; }; - Tree.prototype._setSelectedState = function (node, state, options) { + Tree.prototype._setSelected = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -429,7 +429,7 @@ // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this._setSelectedState(node, false, options); + this._setSelected(node, false, options); }, this)); } @@ -477,12 +477,12 @@ return this; }; - Tree.prototype._toggleCheckedState = function (node, options) { + Tree.prototype._toggleChecked = function (node, options) { if (!node) return; - this._setCheckedState(node, !node.state.checked, options); + this._setChecked(node, !node.state.checked, options); }; - Tree.prototype._setCheckedState = function (node, state, options) { + Tree.prototype._setChecked = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -526,7 +526,7 @@ } }; - Tree.prototype._setDisabledState = function (node, state, options) { + Tree.prototype._setDisabled = function (node, state, options) { // We never pass options when rendering, so the only time // we need to validate state is from user interaction @@ -538,9 +538,9 @@ node.state.disabled = true; // Disable all other states - this._setSelectedState(node, false, options); - this._setCheckedState(node, false, options); - this._setExpandedState(node, false, options); + this._setSelected(node, false, options); + this._setChecked(node, false, options); + this._setExpanded(node, false, options); // Set element if (node.$el) { @@ -661,14 +661,14 @@ } // Set various node states - this._setSelectedState(node, node.state.selected); - this._setCheckedState(node, node.state.checked); + this._setSelected(node, node.state.selected); + this._setChecked(node, node.state.checked); // Set expanded state also triggers recursive tree build - this._setExpandedState(node, node.state.expanded); + this._setExpanded(node, node.state.expanded); // Finally disabled, which will override any of previous states when true - this._setDisabledState(node, node.state.disabled); + this._setDisabled(node, node.state.disabled); }; // Creates a new node element from template and @@ -912,7 +912,7 @@ */ Tree.prototype.selectNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setSelectedState(node, true, options); + this._setSelected(node, true, options); }, this)); }; @@ -923,7 +923,7 @@ */ Tree.prototype.unselectNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setSelectedState(node, false, options); + this._setSelected(node, false, options); }, this)); }; @@ -934,7 +934,7 @@ */ Tree.prototype.toggleNodeSelected = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleSelectedState(node, options); + this._toggleSelected(node, options); }, this)); }; @@ -956,7 +956,7 @@ */ Tree.prototype.collapseNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setExpandedState(node, false, options); + this._setExpanded(node, false, options); }, this)); }; @@ -977,7 +977,7 @@ */ Tree.prototype.expandNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setExpandedState(node, true, options); + this._setExpanded(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); } @@ -986,7 +986,7 @@ Tree.prototype._expandLevels = function (nodes, level, options) { $.each(nodes, $.proxy(function (index, node) { - this._setExpandedState(node, (level > 0) ? true : false, options); + this._setExpanded(node, (level > 0) ? true : false, options); if (node.nodes) { this._expandLevels(node.nodes, level-1, options); } @@ -1004,7 +1004,7 @@ var tmpNode; while (tmpNode = this.getParent(parentNode)) { parentNode = tmpNode; - this._setExpandedState(parentNode, true, options); + this._setExpanded(parentNode, true, options); }; }, this)); }; @@ -1016,7 +1016,7 @@ */ Tree.prototype.toggleNodeExpanded = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleExpandedState(node, options); + this._toggleExpanded(node, options); }, this)); }; @@ -1028,7 +1028,7 @@ Tree.prototype.checkAll = function (options) { var identifiers = this._findNodes('false', 'g', 'state.checked'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, true, options); + this._setChecked(node, true, options); }, this)); }; @@ -1039,7 +1039,7 @@ */ Tree.prototype.checkNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, true, options); + this._setChecked(node, true, options); }, this)); }; @@ -1050,7 +1050,7 @@ Tree.prototype.uncheckAll = function (options) { var identifiers = this._findNodes('true', 'g', 'state.checked'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, false, options); + this._setChecked(node, false, options); }, this)); }; @@ -1061,7 +1061,7 @@ */ Tree.prototype.uncheckNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setCheckedState(node, false, options); + this._setChecked(node, false, options); }, this)); }; @@ -1072,7 +1072,7 @@ */ Tree.prototype.toggleNodeChecked = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._toggleCheckedState(node, options); + this._toggleChecked(node, options); }, this)); }; @@ -1084,7 +1084,7 @@ Tree.prototype.disableAll = function (options) { var identifiers = this._findNodes('false', 'g', 'state.disabled'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, true, options); + this._setDisabled(node, true, options); }, this)); }; @@ -1095,7 +1095,7 @@ */ Tree.prototype.disableNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, true, options); + this._setDisabled(node, true, options); }, this)); }; @@ -1106,7 +1106,7 @@ Tree.prototype.enableAll = function (options) { var identifiers = this._findNodes('true', 'g', 'state.disabled'); this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, false, options); + this._setDisabled(node, false, options); }, this)); }; @@ -1117,7 +1117,7 @@ */ Tree.prototype.enableNode = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, false, options); + this._setDisabled(node, false, options); }, this)); }; @@ -1128,7 +1128,7 @@ */ Tree.prototype.toggleNodeDisabled = function (identifiers, options) { this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabledState(node, !node.state.disabled, options); + this._setDisabled(node, !node.state.disabled, options); }, this)); }; From d6d22a25a353c93d6f2ed07844d7ef01f3116649 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 27 Jun 2015 11:14:58 +0100 Subject: [PATCH 13/52] Fixed issue with highlighting of search results when not visible, plus only changes in results are now set/unset #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 72 ++++++++++++++++++++++++--------- src/js/bootstrap-treeview.js | 72 ++++++++++++++++++++++++--------- tests/lib/bootstrap-treeview.js | 72 ++++++++++++++++++++++++--------- 4 files changed, 163 insertions(+), 55 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 7e72f6273..fe1387b06 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpanded(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                      ',node:'
                                                                    • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch();var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this._findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0,b.$el.addClass("node-result")})}return c.revealResults&&this.revealNode(d),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1,b.$el.removeClass("node-result")});this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpanded(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                        ',node:'
                                                                      • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g),a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e)}return this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index ec17d9894..6f157c265 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -569,6 +569,27 @@ } }; + Tree.prototype._setSearchResult = function (node, state, options) { + if (options && state === node.searchResult) return; + + if (state) { + + node.searchResult = true; + + if (node.$el) { + node.$el.addClass('node-result'); + } + } + else { + + node.searchResult = false; + + if (node.$el) { + node.$el.removeClass('node-result'); + } + } + }; + Tree.prototype._render = function () { if (!this._initialized) { @@ -663,6 +684,7 @@ // Set various node states this._setSelected(node, node.state.selected); this._setChecked(node, node.state.checked); + this._setSearchResult(node, node.searchResult); // Set expanded state also triggers recursive tree build this._setExpanded(node, node.state.expanded); @@ -1167,9 +1189,9 @@ Tree.prototype.search = function (pattern, options) { options = $.extend({}, _default.searchOptions, options); - this.clearSearch(); - + var previous = this._getSearchResults(); var results = []; + if (pattern && pattern.length > 0) { if (options.exactMatch) { @@ -1183,19 +1205,20 @@ results = this._findNodes(pattern, modifier); - // Add searchResult property to all matching nodes - // This will be used to apply custom styles - // and when identifying result to be cleared - $.each(results, function (index, node) { - node.searchResult = true; - node.$el.addClass('node-result'); - }) - } + // Clear previous results no longer matched + $.each(this._diffArray(results, previous), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); - // If revealResults, then render is triggered from revealNode - // otherwise we just call render. - if (options.revealResults) { - this.revealNode(results); + // Set new results + $.each(this._diffArray(previous, results), $.proxy(function (index, node) { + this._setSearchResult(node, true, options); + }, this)); + + // Reveal hidden nodes + if (results && options.revealResults) { + this.revealNode(results); + } } this.$element.trigger('searchComplete', $.extend(true, {}, results)); @@ -1210,14 +1233,27 @@ options = $.extend({}, { render: true }, options); - var results = $.each(this._findNodes('true', 'g', 'searchResult'), function (index, node) { - node.searchResult = false; - node.$el.removeClass('node-result'); - }); + var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; + Tree.prototype._getSearchResults = function () { + return this._findNodes('true', 'g', 'searchResult'); + }; + + Tree.prototype._diffArray = function (a, b) { + var diff = []; + $.grep(b, function (n) { + if ($.inArray(n, a) === -1) { + diff.push(n); + } + }); + return diff; + }; + /** Find nodes that match a given criteria @param {String} pattern - A given string to match against diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index ec17d9894..6f157c265 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -569,6 +569,27 @@ } }; + Tree.prototype._setSearchResult = function (node, state, options) { + if (options && state === node.searchResult) return; + + if (state) { + + node.searchResult = true; + + if (node.$el) { + node.$el.addClass('node-result'); + } + } + else { + + node.searchResult = false; + + if (node.$el) { + node.$el.removeClass('node-result'); + } + } + }; + Tree.prototype._render = function () { if (!this._initialized) { @@ -663,6 +684,7 @@ // Set various node states this._setSelected(node, node.state.selected); this._setChecked(node, node.state.checked); + this._setSearchResult(node, node.searchResult); // Set expanded state also triggers recursive tree build this._setExpanded(node, node.state.expanded); @@ -1167,9 +1189,9 @@ Tree.prototype.search = function (pattern, options) { options = $.extend({}, _default.searchOptions, options); - this.clearSearch(); - + var previous = this._getSearchResults(); var results = []; + if (pattern && pattern.length > 0) { if (options.exactMatch) { @@ -1183,19 +1205,20 @@ results = this._findNodes(pattern, modifier); - // Add searchResult property to all matching nodes - // This will be used to apply custom styles - // and when identifying result to be cleared - $.each(results, function (index, node) { - node.searchResult = true; - node.$el.addClass('node-result'); - }) - } + // Clear previous results no longer matched + $.each(this._diffArray(results, previous), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); - // If revealResults, then render is triggered from revealNode - // otherwise we just call render. - if (options.revealResults) { - this.revealNode(results); + // Set new results + $.each(this._diffArray(previous, results), $.proxy(function (index, node) { + this._setSearchResult(node, true, options); + }, this)); + + // Reveal hidden nodes + if (results && options.revealResults) { + this.revealNode(results); + } } this.$element.trigger('searchComplete', $.extend(true, {}, results)); @@ -1210,14 +1233,27 @@ options = $.extend({}, { render: true }, options); - var results = $.each(this._findNodes('true', 'g', 'searchResult'), function (index, node) { - node.searchResult = false; - node.$el.removeClass('node-result'); - }); + var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; + Tree.prototype._getSearchResults = function () { + return this._findNodes('true', 'g', 'searchResult'); + }; + + Tree.prototype._diffArray = function (a, b) { + var diff = []; + $.grep(b, function (n) { + if ($.inArray(n, a) === -1) { + diff.push(n); + } + }); + return diff; + }; + /** Find nodes that match a given criteria @param {String} pattern - A given string to match against diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index ec17d9894..6f157c265 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -569,6 +569,27 @@ } }; + Tree.prototype._setSearchResult = function (node, state, options) { + if (options && state === node.searchResult) return; + + if (state) { + + node.searchResult = true; + + if (node.$el) { + node.$el.addClass('node-result'); + } + } + else { + + node.searchResult = false; + + if (node.$el) { + node.$el.removeClass('node-result'); + } + } + }; + Tree.prototype._render = function () { if (!this._initialized) { @@ -663,6 +684,7 @@ // Set various node states this._setSelected(node, node.state.selected); this._setChecked(node, node.state.checked); + this._setSearchResult(node, node.searchResult); // Set expanded state also triggers recursive tree build this._setExpanded(node, node.state.expanded); @@ -1167,9 +1189,9 @@ Tree.prototype.search = function (pattern, options) { options = $.extend({}, _default.searchOptions, options); - this.clearSearch(); - + var previous = this._getSearchResults(); var results = []; + if (pattern && pattern.length > 0) { if (options.exactMatch) { @@ -1183,19 +1205,20 @@ results = this._findNodes(pattern, modifier); - // Add searchResult property to all matching nodes - // This will be used to apply custom styles - // and when identifying result to be cleared - $.each(results, function (index, node) { - node.searchResult = true; - node.$el.addClass('node-result'); - }) - } + // Clear previous results no longer matched + $.each(this._diffArray(results, previous), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); - // If revealResults, then render is triggered from revealNode - // otherwise we just call render. - if (options.revealResults) { - this.revealNode(results); + // Set new results + $.each(this._diffArray(previous, results), $.proxy(function (index, node) { + this._setSearchResult(node, true, options); + }, this)); + + // Reveal hidden nodes + if (results && options.revealResults) { + this.revealNode(results); + } } this.$element.trigger('searchComplete', $.extend(true, {}, results)); @@ -1210,14 +1233,27 @@ options = $.extend({}, { render: true }, options); - var results = $.each(this._findNodes('true', 'g', 'searchResult'), function (index, node) { - node.searchResult = false; - node.$el.removeClass('node-result'); - }); + var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; + Tree.prototype._getSearchResults = function () { + return this._findNodes('true', 'g', 'searchResult'); + }; + + Tree.prototype._diffArray = function (a, b) { + var diff = []; + $.grep(b, function (n) { + if ($.inArray(n, a) === -1) { + diff.push(n); + } + }); + return diff; + }; + /** Find nodes that match a given criteria @param {String} pattern - A given string to match against From ec2243e364b842ce895578b883d9656701bd81f8 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 27 Jun 2015 11:21:30 +0100 Subject: [PATCH 14/52] Fixes clear search results when no pattern / results #76 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 24 ++++++++++++------------ src/js/bootstrap-treeview.js | 24 ++++++++++++------------ tests/lib/bootstrap-treeview.js | 24 ++++++++++++------------ 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index fe1387b06..93df898d9 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpanded(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                          ',node:'
                                                                        • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g),a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e)}return this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpanded(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                            ',node:'
                                                                          • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 6f157c265..36a04cabd 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -1204,21 +1204,21 @@ } results = this._findNodes(pattern, modifier); + } - // Clear previous results no longer matched - $.each(this._diffArray(results, previous), $.proxy(function (index, node) { - this._setSearchResult(node, false, options); - }, this)); + // Clear previous results no longer matched + $.each(this._diffArray(results, previous), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); - // Set new results - $.each(this._diffArray(previous, results), $.proxy(function (index, node) { - this._setSearchResult(node, true, options); - }, this)); + // Set new results + $.each(this._diffArray(previous, results), $.proxy(function (index, node) { + this._setSearchResult(node, true, options); + }, this)); - // Reveal hidden nodes - if (results && options.revealResults) { - this.revealNode(results); - } + // Reveal hidden nodes + if (results && options.revealResults) { + this.revealNode(results); } this.$element.trigger('searchComplete', $.extend(true, {}, results)); diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 6f157c265..36a04cabd 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -1204,21 +1204,21 @@ } results = this._findNodes(pattern, modifier); + } - // Clear previous results no longer matched - $.each(this._diffArray(results, previous), $.proxy(function (index, node) { - this._setSearchResult(node, false, options); - }, this)); + // Clear previous results no longer matched + $.each(this._diffArray(results, previous), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); - // Set new results - $.each(this._diffArray(previous, results), $.proxy(function (index, node) { - this._setSearchResult(node, true, options); - }, this)); + // Set new results + $.each(this._diffArray(previous, results), $.proxy(function (index, node) { + this._setSearchResult(node, true, options); + }, this)); - // Reveal hidden nodes - if (results && options.revealResults) { - this.revealNode(results); - } + // Reveal hidden nodes + if (results && options.revealResults) { + this.revealNode(results); } this.$element.trigger('searchComplete', $.extend(true, {}, results)); diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 6f157c265..36a04cabd 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -1204,21 +1204,21 @@ } results = this._findNodes(pattern, modifier); + } - // Clear previous results no longer matched - $.each(this._diffArray(results, previous), $.proxy(function (index, node) { - this._setSearchResult(node, false, options); - }, this)); + // Clear previous results no longer matched + $.each(this._diffArray(results, previous), $.proxy(function (index, node) { + this._setSearchResult(node, false, options); + }, this)); - // Set new results - $.each(this._diffArray(previous, results), $.proxy(function (index, node) { - this._setSearchResult(node, true, options); - }, this)); + // Set new results + $.each(this._diffArray(previous, results), $.proxy(function (index, node) { + this._setSearchResult(node, true, options); + }, this)); - // Reveal hidden nodes - if (results && options.revealResults) { - this.revealNode(results); - } + // Reveal hidden nodes + if (results && options.revealResults) { + this.revealNode(results); } this.$element.trigger('searchComplete', $.extend(true, {}, results)); From e439fd38fe49baf117f611522be9cdbdef1e06ed Mon Sep 17 00:00:00 2001 From: jonmiles Date: Tue, 17 Nov 2015 15:50:45 +0000 Subject: [PATCH 15/52] Fixed final issue with conversion, whereby revealResults would add non-immediate children out of position (at the end) #76 - Added state.visible which controls whether a node is visible or not (display:none) and refactored to render all nodes all the time --- dist/bootstrap-treeview.min.css | 2 +- dist/bootstrap-treeview.min.js | 2 +- public/css/bootstrap-treeview.css | 4 ++ public/js/bootstrap-treeview.js | 74 +++++++++++++++++++++---------- src/css/bootstrap-treeview.css | 4 ++ src/js/bootstrap-treeview.js | 74 +++++++++++++++++++++---------- tests/lib/bootstrap-treeview.css | 4 ++ tests/lib/bootstrap-treeview.js | 74 +++++++++++++++++++++---------- 8 files changed, 167 insertions(+), 71 deletions(-) diff --git a/dist/bootstrap-treeview.min.css b/dist/bootstrap-treeview.min.css index 57a348a87..b64a53bec 100644 --- a/dist/bootstrap-treeview.min.css +++ b/dist/bootstrap-treeview.min.css @@ -1 +1 @@ -.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed} \ No newline at end of file +.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}.treeview .node-hidden{display:none} \ No newline at end of file diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 93df898d9..e92540ce6 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),this._expandNode(b),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this._setExpanded(b,!1,d)},this)),this._collapseNode(b),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                              ',node:'
                                                                            • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.visible=c>e._options.levels?!1:!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                ',node:'
                                                                              • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/css/bootstrap-treeview.css b/public/css/bootstrap-treeview.css index 62ea91fc1..6378f2d01 100644 --- a/public/css/bootstrap-treeview.css +++ b/public/css/bootstrap-treeview.css @@ -35,3 +35,7 @@ color: silver; cursor: not-allowed; } + +.treeview .node-hidden { + display: none; +} \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 36a04cabd..23d3c4e71 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -300,6 +300,14 @@ } } + // set visible state; based purely on levels + if (level > _this._options.levels) { + node.state.visible = false; + } + else { + node.state.visible = true; + } + // set selected state; unless set always false if (!node.state.hasOwnProperty('selected')) { node.state.selected = false; @@ -375,8 +383,12 @@ .addClass(this._options.collapseIcon); } - // Render child nodes - this._expandNode(node); + // Expand children + if (node.nodes && options) { + $.each(node.nodes, $.proxy(function (index, node) { + this._setVisible(node, true, options); + }, this)); + } // Optionally trigger event if (options && !options.silent) { @@ -396,15 +408,13 @@ } // Collapse children - if (node.nodes && options && !options.ignoreChildren) { + if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { + this._setVisible(node, false, options); this._setExpanded(node, false, options); }, this)); } - // Remove child nodes - this._collapseNode(node); - // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); @@ -412,6 +422,32 @@ } }; + Tree.prototype._setVisible = function (node, state, options) { + + if (options && state === node.state.visible) return; + + if (state) { + + // Set node state + node.state.visible = true; + + // Set element + if (node.$el) { + node.$el.removeClass('node-hidden'); + } + } + else { + + // Set node state to unchecked + node.state.visible = false; + + // Set element + if (node.$el) { + node.$el.addClass('node-hidden'); + } + } + }; + Tree.prototype._toggleSelected = function (node, options) { if (!node) return; this._setSelected(node, !node.state.selected, options); @@ -685,12 +721,17 @@ this._setSelected(node, node.state.selected); this._setChecked(node, node.state.checked); this._setSearchResult(node, node.searchResult); - - // Set expanded state also triggers recursive tree build this._setExpanded(node, node.state.expanded); - - // Finally disabled, which will override any of previous states when true this._setDisabled(node, node.state.disabled); + this._setVisible(node, node.state.visible); + + // If children exist, recursively add + if (node.nodes) { + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, node.$el); + }, this)); + } }; // Creates a new node element from template and @@ -710,19 +751,6 @@ return $el; }; - // Collapse node, removing it's immediate children - Tree.prototype._collapseNode = function (node) { - if (!node.nodes) return; - - $.each(node.nodes, $.proxy(function (index, node) { - this._collapseNode(node); - if (node.$el) { - node.$el.remove(); - node.$el = null; - } - }, this)); - }; - // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; diff --git a/src/css/bootstrap-treeview.css b/src/css/bootstrap-treeview.css index 62ea91fc1..6378f2d01 100644 --- a/src/css/bootstrap-treeview.css +++ b/src/css/bootstrap-treeview.css @@ -35,3 +35,7 @@ color: silver; cursor: not-allowed; } + +.treeview .node-hidden { + display: none; +} \ No newline at end of file diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 36a04cabd..23d3c4e71 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -300,6 +300,14 @@ } } + // set visible state; based purely on levels + if (level > _this._options.levels) { + node.state.visible = false; + } + else { + node.state.visible = true; + } + // set selected state; unless set always false if (!node.state.hasOwnProperty('selected')) { node.state.selected = false; @@ -375,8 +383,12 @@ .addClass(this._options.collapseIcon); } - // Render child nodes - this._expandNode(node); + // Expand children + if (node.nodes && options) { + $.each(node.nodes, $.proxy(function (index, node) { + this._setVisible(node, true, options); + }, this)); + } // Optionally trigger event if (options && !options.silent) { @@ -396,15 +408,13 @@ } // Collapse children - if (node.nodes && options && !options.ignoreChildren) { + if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { + this._setVisible(node, false, options); this._setExpanded(node, false, options); }, this)); } - // Remove child nodes - this._collapseNode(node); - // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); @@ -412,6 +422,32 @@ } }; + Tree.prototype._setVisible = function (node, state, options) { + + if (options && state === node.state.visible) return; + + if (state) { + + // Set node state + node.state.visible = true; + + // Set element + if (node.$el) { + node.$el.removeClass('node-hidden'); + } + } + else { + + // Set node state to unchecked + node.state.visible = false; + + // Set element + if (node.$el) { + node.$el.addClass('node-hidden'); + } + } + }; + Tree.prototype._toggleSelected = function (node, options) { if (!node) return; this._setSelected(node, !node.state.selected, options); @@ -685,12 +721,17 @@ this._setSelected(node, node.state.selected); this._setChecked(node, node.state.checked); this._setSearchResult(node, node.searchResult); - - // Set expanded state also triggers recursive tree build this._setExpanded(node, node.state.expanded); - - // Finally disabled, which will override any of previous states when true this._setDisabled(node, node.state.disabled); + this._setVisible(node, node.state.visible); + + // If children exist, recursively add + if (node.nodes) { + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, node.$el); + }, this)); + } }; // Creates a new node element from template and @@ -710,19 +751,6 @@ return $el; }; - // Collapse node, removing it's immediate children - Tree.prototype._collapseNode = function (node) { - if (!node.nodes) return; - - $.each(node.nodes, $.proxy(function (index, node) { - this._collapseNode(node); - if (node.$el) { - node.$el.remove(); - node.$el = null; - } - }, this)); - }; - // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; diff --git a/tests/lib/bootstrap-treeview.css b/tests/lib/bootstrap-treeview.css index 62ea91fc1..6378f2d01 100644 --- a/tests/lib/bootstrap-treeview.css +++ b/tests/lib/bootstrap-treeview.css @@ -35,3 +35,7 @@ color: silver; cursor: not-allowed; } + +.treeview .node-hidden { + display: none; +} \ No newline at end of file diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 36a04cabd..23d3c4e71 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -300,6 +300,14 @@ } } + // set visible state; based purely on levels + if (level > _this._options.levels) { + node.state.visible = false; + } + else { + node.state.visible = true; + } + // set selected state; unless set always false if (!node.state.hasOwnProperty('selected')) { node.state.selected = false; @@ -375,8 +383,12 @@ .addClass(this._options.collapseIcon); } - // Render child nodes - this._expandNode(node); + // Expand children + if (node.nodes && options) { + $.each(node.nodes, $.proxy(function (index, node) { + this._setVisible(node, true, options); + }, this)); + } // Optionally trigger event if (options && !options.silent) { @@ -396,15 +408,13 @@ } // Collapse children - if (node.nodes && options && !options.ignoreChildren) { + if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { + this._setVisible(node, false, options); this._setExpanded(node, false, options); }, this)); } - // Remove child nodes - this._collapseNode(node); - // Optionally trigger event if (options && !options.silent) { this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); @@ -412,6 +422,32 @@ } }; + Tree.prototype._setVisible = function (node, state, options) { + + if (options && state === node.state.visible) return; + + if (state) { + + // Set node state + node.state.visible = true; + + // Set element + if (node.$el) { + node.$el.removeClass('node-hidden'); + } + } + else { + + // Set node state to unchecked + node.state.visible = false; + + // Set element + if (node.$el) { + node.$el.addClass('node-hidden'); + } + } + }; + Tree.prototype._toggleSelected = function (node, options) { if (!node) return; this._setSelected(node, !node.state.selected, options); @@ -685,12 +721,17 @@ this._setSelected(node, node.state.selected); this._setChecked(node, node.state.checked); this._setSearchResult(node, node.searchResult); - - // Set expanded state also triggers recursive tree build this._setExpanded(node, node.state.expanded); - - // Finally disabled, which will override any of previous states when true this._setDisabled(node, node.state.disabled); + this._setVisible(node, node.state.visible); + + // If children exist, recursively add + if (node.nodes) { + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { + childNode.level = node.level + 1; + this._renderNode(childNode, node.$el); + }, this)); + } }; // Creates a new node element from template and @@ -710,19 +751,6 @@ return $el; }; - // Collapse node, removing it's immediate children - Tree.prototype._collapseNode = function (node) { - if (!node.nodes) return; - - $.each(node.nodes, $.proxy(function (index, node) { - this._collapseNode(node); - if (node.$el) { - node.$el.remove(); - node.$el = null; - } - }, this)); - }; - // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; From 60397318e1d62fba26d933b6bd2530575019ba73 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Tue, 17 Nov 2015 15:57:57 +0000 Subject: [PATCH 16/52] Tidy up code smells --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 7 +++---- src/js/bootstrap-treeview.js | 7 +++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index e92540ce6..613e252b1 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.visible=c>e._options.levels?!1:!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                  ',node:'
                                                                                • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this._nodes,function(a){var f=e._getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.visible=c>e._options.levels?!1:!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                    ',node:'
                                                                                  • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 23d3c4e71..c3fe06485 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -1294,13 +1294,12 @@ modifier = modifier || 'g'; attribute = attribute || 'text'; - var _this = this; - return $.grep(this._nodes, function (node) { - var val = _this._getNodeValue(node, attribute); + return $.grep(this._nodes, $.proxy(function (node) { + var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } - }); + }, this)); }; /** diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 23d3c4e71..c3fe06485 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -1294,13 +1294,12 @@ modifier = modifier || 'g'; attribute = attribute || 'text'; - var _this = this; - return $.grep(this._nodes, function (node) { - var val = _this._getNodeValue(node, attribute); + return $.grep(this._nodes, $.proxy(function (node) { + var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } - }); + }, this)); }; /** From cf40984e09573173619448cc7ae17250e1794776 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Tue, 17 Nov 2015 15:59:01 +0000 Subject: [PATCH 17/52] Updated broken test after state.visible refactor #76 --- tests/lib/bootstrap-treeview.js | 7 ++- tests/tests.js | 96 ++++++++++++++++----------------- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 23d3c4e71..c3fe06485 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -1294,13 +1294,12 @@ modifier = modifier || 'g'; attribute = attribute || 'text'; - var _this = this; - return $.grep(this._nodes, function (node) { - var val = _this._getNodeValue(node, attribute); + return $.grep(this._nodes, $.proxy(function (node) { + var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } - }); + }, this)); }; /** diff --git a/tests/tests.js b/tests/tests.js index 845bcee4c..377881e0f 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -209,7 +209,7 @@ test('Accepts JSON', function () { var el = init({levels:1,data:json}); - equal($(el.selector + ' ul li').length, 5, 'Correct number of root nodes'); + equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); }); @@ -224,19 +224,19 @@ test('Correct initial levels shown', function () { var el = init({levels:1,data:data}); - equal($(el.selector + ' ul li').length, 5, 'Correctly display 5 root nodes when levels set to 1'); + equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correctly display 5 root nodes when levels set to 1'); el = init({levels:2,data:data}); - equal($(el.selector + ' ul li').length, 7, 'Correctly display 5 root and 2 child nodes when levels set to 2'); + equal($(el.selector + ' ul li:not(.node-hidden)').length, 7, 'Correctly display 5 root and 2 child nodes when levels set to 2'); el = init({levels:3,data:data}); - equal($(el.selector + ' ul li').length, 9, 'Correctly display 5 root, 2 children and 2 grand children nodes when levels set to 3'); + equal($(el.selector + ' ul li:not(.node-hidden)').length, 9, 'Correctly display 5 root, 2 children and 2 grand children nodes when levels set to 3'); }); test('Expanding a node', function () { var cbWorked, onWorked = false; - init({ + var el = init({ data: data, levels: 1, onNodeExpanded: function(/*event, date*/) { @@ -247,10 +247,10 @@ onWorked = true; }); - var nodeCount = $('.list-group-item').length; - var el = $('.expand-icon:first'); - el.trigger('click'); - ok(($('.list-group-item').length > nodeCount), 'Number of nodes are increased, so node must have expanded'); + var nodeCount = $(el.selector + ' ul li:not(.node-hidden)').length; + var firstNode = $('.expand-icon:first'); + firstNode.trigger('click'); + ok(($(el.selector + ' ul li:not(.node-hidden)').length > nodeCount), 'Number of nodes are increased, so node must have expanded'); ok(cbWorked, 'onNodeExpanded function was called'); ok(onWorked, 'nodeExpanded was fired'); }); @@ -258,7 +258,7 @@ test('Collapsing a node', function () { var cbWorked, onWorked = false; - init({ + var el = init({ data: data, levels: 2, onNodeCollapsed: function(/*event, date*/) { @@ -269,10 +269,10 @@ onWorked = true; }); - var nodeCount = $('.list-group-item').length; - var el = $('.expand-icon:first'); - el.trigger('click'); - ok(($('.list-group-item').length < nodeCount), 'Number of nodes has decreased, so node must have collapsed'); + var nodeCount = $(el.selector + ' ul li:not(.node-hidden)').length; + var firstNode = $('.expand-icon:first'); + firstNode.trigger('click'); + ok(($(el.selector + ' ul li:not(.node-hidden)').length < nodeCount), 'Number of nodes has decreased, so node must have collapsed'); ok(cbWorked, 'onNodeCollapsed function was called'); ok(onWorked, 'nodeCollapsed was fired'); }); @@ -367,7 +367,7 @@ testData[0].selectable = false; var cbCalled, onCalled = false; - init({ + var el = init({ levels: 1, data: testData, onNodeSelected: function(/*event, date*/) { @@ -378,14 +378,14 @@ onCalled = true; }); - var nodeCount = $('.list-group-item').length; - var el = $('.list-group-item:first'); - el.trigger('click'); - el = $('.list-group-item:first'); - ok(!el.hasClass('node-selected'), 'Node should not be selected'); + var nodeCount = $(el.selector + ' ul li:not(.node-hidden)').length; + var firstNode = $('.list-group-item:first'); + firstNode.trigger('click'); + firstNode = $('.list-group-item:first'); + ok(!firstNode.hasClass('node-selected'), 'Node should not be selected'); ok(!cbCalled, 'onNodeSelected function should not be called'); ok(!onCalled, 'nodeSelected should not fire'); - ok(($('.list-group-item').length > nodeCount), 'Number of nodes are increased, so node must have expanded'); + ok(($(el.selector + ' ul li:not(.node-hidden)').length > nodeCount), 'Number of nodes are increased, so node must have expanded'); }); test('Clicking a non-selectable, expanded node collapses the node', function () { @@ -393,7 +393,7 @@ testData[0].selectable = false; var cbCalled, onCalled = false; - init({ + var el = init({ levels: 2, data: testData, onNodeSelected: function(/*event, date*/) { @@ -404,15 +404,15 @@ onCalled = true; }); - var nodeCount = $('.list-group-item').length; - var el = $('.list-group-item:first'); - el.trigger('click'); - el = $('.list-group-item:first'); + var nodeCount = $(el.selector + ' ul li:not(.node-hidden)').length; + var firstNode = $('.list-group-item:first'); + firstNode.trigger('click'); + firstNode = $('.list-group-item:first'); - ok(!el.hasClass('node-selected'), 'Node should not be selected'); + ok(!firstNode.hasClass('node-selected'), 'Node should not be selected'); ok(!cbCalled, 'onNodeSelected function should not be called'); ok(!onCalled, 'nodeSelected should not fire'); - ok(($('.list-group-item').length < nodeCount), 'Number of nodes has decreased, so node must have collapsed'); + ok(($(el.selector + ' ul li:not(.node-hidden)').length < nodeCount), 'Number of nodes has decreased, so node must have collapsed'); }); test('Checking a node', function () { @@ -600,10 +600,10 @@ var $tree = init({ data: data, levels: 1 }); $tree.treeview('disableAll'); - equal($($tree.selector + ' ul li.node-disabled').length, 5, 'Disable all works, 9 nodes with node-disabled class'); + equal($($tree.selector + ' ul li:not(.node-hidden).node-disabled').length, 5, 'Disable all works, 9 nodes with node-disabled class'); $tree.treeview('enableAll'); - equal($($tree.selector + ' ul li.node-disabled').length, 0, 'Check all works, 9 nodes non with node-disabled class'); + equal($($tree.selector + ' ul li:not(.node-hidden).node-disabled').length, 0, 'Check all works, 9 nodes non with node-disabled class'); }); test('disableNode / enableNode', function () { @@ -754,66 +754,66 @@ test('expandAll / collapseAll', function () { var $tree = init({ data: data, levels: 1 }); - equal($($tree.selector + ' ul li').length, 5, 'Starts in collapsed state, 5 root nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Starts in collapsed state, 5 root nodes displayed'); $tree.treeview('expandAll'); - equal($($tree.selector + ' ul li').length, 9, 'Expand all works, all 9 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Expand all works, all 9 nodes displayed'); $tree.treeview('collapseAll'); - equal($($tree.selector + ' ul li').length, 5, 'Collapse all works, 5 original root nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse all works, 5 original root nodes displayed'); $tree.treeview('expandAll', { levels: 1 }); - equal($($tree.selector + ' ul li').length, 7, 'Expand all (levels = 1) works, correctly displayed 7 nodes'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand all (levels = 1) works, correctly displayed 7 nodes'); }); test('expandNode / collapseNode / toggleExpanded', function () { var $tree = init({ data: data, levels: 1 }); - equal($($tree.selector + ' ul li').length, 5, 'Starts in collapsed state, 5 root nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Starts in collapsed state, 5 root nodes displayed'); $tree.treeview('expandNode', 0); - equal($($tree.selector + ' ul li').length, 7, 'Expand node (by id) works, 7 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand node (by id) works, 7 nodes displayed'); $tree.treeview('collapseNode', 0); - equal($($tree.selector + ' ul li').length, 5, 'Collapse node (by id) works, 5 original nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse node (by id) works, 5 original nodes displayed'); $tree.treeview('toggleNodeExpanded', 0); - equal($($tree.selector + ' ul li').length, 7, 'Toggle node (by id) works, 7 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Toggle node (by id) works, 7 nodes displayed'); $tree.treeview('toggleNodeExpanded', 0); - equal($($tree.selector + ' ul li').length, 5, 'Toggle node (by id) works, 5 original nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Toggle node (by id) works, 5 original nodes displayed'); $tree.treeview('expandNode', [ 0, { levels: 2 } ]); - equal($($tree.selector + ' ul li').length, 9, 'Expand node (levels = 2, by id) works, 9 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Expand node (levels = 2, by id) works, 9 nodes displayed'); $tree = init({ data: data, levels: 1 }); - equal($($tree.selector + ' ul li').length, 5, 'Reset to collapsed state, 5 root nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Reset to collapsed state, 5 root nodes displayed'); var nodeParent1 = $tree.treeview('getNode', 0); $tree.treeview('expandNode', nodeParent1); - equal($($tree.selector + ' ul li').length, 7, 'Expand node (by node) works, 7 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand node (by node) works, 7 nodes displayed'); $tree.treeview('collapseNode', nodeParent1); - equal($($tree.selector + ' ul li').length, 5, 'Collapse node (by node) works, 5 original nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse node (by node) works, 5 original nodes displayed'); $tree.treeview('toggleNodeExpanded', nodeParent1); - equal($($tree.selector + ' ul li').length, 7, 'Toggle node (by node) works, 7 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Toggle node (by node) works, 7 nodes displayed'); $tree.treeview('toggleNodeExpanded', nodeParent1); - equal($($tree.selector + ' ul li').length, 5, 'Toggle node (by node) works, 5 original nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Toggle node (by node) works, 5 original nodes displayed'); $tree.treeview('expandNode', [ nodeParent1, { levels: 2 } ]); - equal($($tree.selector + ' ul li').length, 9, 'Expand node (levels = 2, by node) works, 9 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Expand node (levels = 2, by node) works, 9 nodes displayed'); }); test('revealNode', function () { var $tree = init({ data: data, levels: 1 }); $tree.treeview('revealNode', 1); // Child_1 - equal($($tree.selector + ' ul li').length, 7, 'Reveal node (by id) works, reveal Child 1 and 7 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Reveal node (by id) works, reveal Child 1 and 7 nodes displayed'); var nodeGrandchild1 = $tree.treeview('getNode', 2); // Grandchild 1 $tree.treeview('revealNode', nodeGrandchild1); - equal($($tree.selector + ' ul li').length, 9, 'Reveal node (by node) works, reveal Grandchild 1 and 9 nodes displayed'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Reveal node (by node) works, reveal Grandchild 1 and 9 nodes displayed'); }); test('search', function () { From a9bdacd012831c6072c642414ab37b6f6b809aa9 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Tue, 17 Nov 2015 16:28:34 +0000 Subject: [PATCH 18/52] Remove any invalid child node (.nodes) during the initial parse (i.e. setInitialStates). Fixes #96 --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 7 ++++++- src/js/bootstrap-treeview.js | 7 ++++++- tests/lib/bootstrap-treeview.js | 7 ++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 613e252b1..543841071 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.visible=c>e._options.levels?!1:!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&e._setInitialStates(b,c)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                      ',node:'
                                                                                    • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.visible=c>e._options.levels?!1:!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                        ',node:'
                                                                                      • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index c3fe06485..7e35eae0c 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -318,7 +318,12 @@ // recurse child nodes and transverse the tree if (node.nodes) { - _this._setInitialStates(node, level); + if (node.nodes.length > 0) { + _this._setInitialStates(node, level); + } + else { + delete node.nodes; + } } }); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index c3fe06485..7e35eae0c 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -318,7 +318,12 @@ // recurse child nodes and transverse the tree if (node.nodes) { - _this._setInitialStates(node, level); + if (node.nodes.length > 0) { + _this._setInitialStates(node, level); + } + else { + delete node.nodes; + } } }); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index c3fe06485..7e35eae0c 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -318,7 +318,12 @@ // recurse child nodes and transverse the tree if (node.nodes) { - _this._setInitialStates(node, level); + if (node.nodes.length > 0) { + _this._setInitialStates(node, level); + } + else { + delete node.nodes; + } } }); }; From 4e3fe48ab14e77ab08b1e234cb65b5a219b20fab Mon Sep 17 00:00:00 2001 From: jonmiles Date: Tue, 17 Nov 2015 16:39:45 +0000 Subject: [PATCH 19/52] Documentation updated to add missing `getChecked` + `getUnchecked` methods. Closes #134 --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index c0a724235..ba6ee13cf 100644 --- a/README.md +++ b/README.md @@ -513,6 +513,14 @@ $('#tree').treeview('expandNode', [ nodeId, { levels: 2, silent: true } ]); Triggers `nodeExpanded` event; pass silent to suppress events. +#### getChecked() + +Returns an array of checked nodes e.g. state.checked = true. + +```javascript +$('#tree').treeview('getChecked', nodeId); +``` + #### getCollapsed() Returns an array of collapsed nodes e.g. state.expanded = false. @@ -577,6 +585,14 @@ Returns an array of sibling nodes for a given node, if valid otherwise returns u $('#tree').treeview('getSiblings', node); ``` +#### getUnchecked() + +Returns an array of unchecked nodes e.g. state.checked = false. + +```javascript +$('#tree').treeview('getUnchecked', nodeId); +``` + #### getUnselected() Returns an array of unselected nodes e.g. state.selected = false. From eed905f39b5989e4729fd2223d7bcb634a75b8ec Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 12:22:38 +0100 Subject: [PATCH 20/52] Remove hyperlink support --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 38 +++++++++++---------------------- src/js/bootstrap-treeview.js | 38 +++++++++++---------------------- tests/lib/bootstrap-treeview.js | 38 +++++++++++---------------------- tests/tests.js | 15 +++---------- 5 files changed, 40 insertions(+), 91 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 543841071..7acf91091 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(b.state.expanded=!b.state.disabled&&c0?!0:!1),b.state.visible=c>e._options.levels?!1:!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){this._options.enableLinks||b.preventDefault();var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                          ',node:'
                                                                                        • ',indent:'',icon:'',link:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                            ',node:'
                                                                                          • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 7e35eae0c..c420b8f1c 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -41,16 +41,15 @@ checkedIcon: 'glyphicon glyphicon-check', uncheckedIcon: 'glyphicon glyphicon-unchecked', - color: undefined, // '#000000', - backColor: undefined, // '#FFFFFF', - borderColor: undefined, // '#dddddd', + color: undefined, + backColor: undefined, + borderColor: undefined, onhoverColor: '#F5F5F5', selectedColor: '#FFFFFF', selectedBackColor: '#428bca', searchResultColor: '#D9534F', - searchResultBackColor: undefined, //'#FFFFFF', + searchResultBackColor: undefined, - enableLinks: false, highlightSelected: true, highlightSearchResults: true, showBorder: true, @@ -330,8 +329,6 @@ Tree.prototype._clickHandler = function (event) { - if (!this._options.enableLinks) event.preventDefault(); - var target = $(event.target); var node = this.targetNode(target); if (!node || node.state.disabled) return; @@ -388,7 +385,7 @@ .addClass(this._options.collapseIcon); } - // Expand children + // Expand children if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { this._setVisible(node, true, options); @@ -412,7 +409,7 @@ .addClass(this._options.expandIcon); } - // Collapse children + // Collapse children if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { this._setVisible(node, false, options); @@ -700,17 +697,7 @@ } // Add text - if (this._options.enableLinks) { - node.$el - .append($(this._template.link) - .attr('href', node.href) - .append(node.text) - ); - } - else { - node.$el - .append(node.text); - } + node.$el.append(node.text); // Add tags as badges if (this._options.showTags && node.tags) { @@ -744,7 +731,7 @@ Tree.prototype._newNodeEl = function (pEl) { var $el = $(this._template.node); - + if (pEl) { this.$wrapper.children() .eq(pEl.index()).after($el); @@ -805,7 +792,7 @@ // Style search results if (this._options.highlightSearchResults && (this._options.searchResultColor || this._options.searchResultBackColor)) { - + var innerStyle = '' if (this._options.searchResultColor) { innerStyle += 'color:' + this._options.searchResultColor + ';'; @@ -820,7 +807,7 @@ // Style selected nodes if (this._options.highlightSelected && (this._options.selectedColor || this._options.selectedBackColor)) { - + var innerStyle = '' if (this._options.selectedColor) { innerStyle += 'color:' + this._options.selectedColor + ';'; @@ -855,7 +842,6 @@ node: '
                                                                                          • ', indent: '', icon: '', - link: '', badge: '' }; @@ -1201,7 +1187,7 @@ $.each(identifiers, $.proxy(function (index, identifier) { callback(this._identifyNode(identifier), options); - }, this)); + }, this)); }; /* @@ -1269,7 +1255,7 @@ var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { this._setSearchResult(node, false, options); }, this)); - + this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 7e35eae0c..c420b8f1c 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -41,16 +41,15 @@ checkedIcon: 'glyphicon glyphicon-check', uncheckedIcon: 'glyphicon glyphicon-unchecked', - color: undefined, // '#000000', - backColor: undefined, // '#FFFFFF', - borderColor: undefined, // '#dddddd', + color: undefined, + backColor: undefined, + borderColor: undefined, onhoverColor: '#F5F5F5', selectedColor: '#FFFFFF', selectedBackColor: '#428bca', searchResultColor: '#D9534F', - searchResultBackColor: undefined, //'#FFFFFF', + searchResultBackColor: undefined, - enableLinks: false, highlightSelected: true, highlightSearchResults: true, showBorder: true, @@ -330,8 +329,6 @@ Tree.prototype._clickHandler = function (event) { - if (!this._options.enableLinks) event.preventDefault(); - var target = $(event.target); var node = this.targetNode(target); if (!node || node.state.disabled) return; @@ -388,7 +385,7 @@ .addClass(this._options.collapseIcon); } - // Expand children + // Expand children if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { this._setVisible(node, true, options); @@ -412,7 +409,7 @@ .addClass(this._options.expandIcon); } - // Collapse children + // Collapse children if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { this._setVisible(node, false, options); @@ -700,17 +697,7 @@ } // Add text - if (this._options.enableLinks) { - node.$el - .append($(this._template.link) - .attr('href', node.href) - .append(node.text) - ); - } - else { - node.$el - .append(node.text); - } + node.$el.append(node.text); // Add tags as badges if (this._options.showTags && node.tags) { @@ -744,7 +731,7 @@ Tree.prototype._newNodeEl = function (pEl) { var $el = $(this._template.node); - + if (pEl) { this.$wrapper.children() .eq(pEl.index()).after($el); @@ -805,7 +792,7 @@ // Style search results if (this._options.highlightSearchResults && (this._options.searchResultColor || this._options.searchResultBackColor)) { - + var innerStyle = '' if (this._options.searchResultColor) { innerStyle += 'color:' + this._options.searchResultColor + ';'; @@ -820,7 +807,7 @@ // Style selected nodes if (this._options.highlightSelected && (this._options.selectedColor || this._options.selectedBackColor)) { - + var innerStyle = '' if (this._options.selectedColor) { innerStyle += 'color:' + this._options.selectedColor + ';'; @@ -855,7 +842,6 @@ node: '
                                                                                          • ', indent: '', icon: '', - link: '', badge: '' }; @@ -1201,7 +1187,7 @@ $.each(identifiers, $.proxy(function (index, identifier) { callback(this._identifyNode(identifier), options); - }, this)); + }, this)); }; /* @@ -1269,7 +1255,7 @@ var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { this._setSearchResult(node, false, options); }, this)); - + this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 7e35eae0c..c420b8f1c 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -41,16 +41,15 @@ checkedIcon: 'glyphicon glyphicon-check', uncheckedIcon: 'glyphicon glyphicon-unchecked', - color: undefined, // '#000000', - backColor: undefined, // '#FFFFFF', - borderColor: undefined, // '#dddddd', + color: undefined, + backColor: undefined, + borderColor: undefined, onhoverColor: '#F5F5F5', selectedColor: '#FFFFFF', selectedBackColor: '#428bca', searchResultColor: '#D9534F', - searchResultBackColor: undefined, //'#FFFFFF', + searchResultBackColor: undefined, - enableLinks: false, highlightSelected: true, highlightSearchResults: true, showBorder: true, @@ -330,8 +329,6 @@ Tree.prototype._clickHandler = function (event) { - if (!this._options.enableLinks) event.preventDefault(); - var target = $(event.target); var node = this.targetNode(target); if (!node || node.state.disabled) return; @@ -388,7 +385,7 @@ .addClass(this._options.collapseIcon); } - // Expand children + // Expand children if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { this._setVisible(node, true, options); @@ -412,7 +409,7 @@ .addClass(this._options.expandIcon); } - // Collapse children + // Collapse children if (node.nodes && options) { $.each(node.nodes, $.proxy(function (index, node) { this._setVisible(node, false, options); @@ -700,17 +697,7 @@ } // Add text - if (this._options.enableLinks) { - node.$el - .append($(this._template.link) - .attr('href', node.href) - .append(node.text) - ); - } - else { - node.$el - .append(node.text); - } + node.$el.append(node.text); // Add tags as badges if (this._options.showTags && node.tags) { @@ -744,7 +731,7 @@ Tree.prototype._newNodeEl = function (pEl) { var $el = $(this._template.node); - + if (pEl) { this.$wrapper.children() .eq(pEl.index()).after($el); @@ -805,7 +792,7 @@ // Style search results if (this._options.highlightSearchResults && (this._options.searchResultColor || this._options.searchResultBackColor)) { - + var innerStyle = '' if (this._options.searchResultColor) { innerStyle += 'color:' + this._options.searchResultColor + ';'; @@ -820,7 +807,7 @@ // Style selected nodes if (this._options.highlightSelected && (this._options.selectedColor || this._options.selectedBackColor)) { - + var innerStyle = '' if (this._options.selectedColor) { innerStyle += 'color:' + this._options.selectedColor + ';'; @@ -855,7 +842,6 @@ node: '
                                                                                          • ', indent: '', icon: '', - link: '', badge: '' }; @@ -1201,7 +1187,7 @@ $.each(identifiers, $.proxy(function (index, identifier) { callback(this._identifyNode(identifier), options); - }, this)); + }, this)); }; /* @@ -1269,7 +1255,7 @@ var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { this._setSearchResult(node, false, options); }, this)); - + this.$element.trigger('searchCleared', $.extend(true, {}, results)); }; diff --git a/tests/tests.js b/tests/tests.js index 377881e0f..da379b492 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -103,7 +103,6 @@ equal(options.selectedBackColor, '#428bca', 'selectedBackColor default ok'); equal(options.searchResultColor, '#D9534F', 'searchResultColor default ok'); equal(options.searchResultBackColor, undefined, 'searchResultBackColor default ok'); - equal(options.enableLinks, false, 'enableLinks default ok'); equal(options.highlightSelected, true, 'highlightSelected default ok'); equal(options.highlightSearchResults, true, 'highlightSearchResults default ok'); equal(options.showBorder, true, 'showBorder default ok'); @@ -140,7 +139,6 @@ selectedBackColor: 'darkorange', searchResultColor: 'yellow', searchResultBackColor: 'darkorange', - enableLinks: true, highlightSelected: false, highlightSearchResults: true, showBorder: false, @@ -178,7 +176,6 @@ equal(options.selectedBackColor, 'darkorange', 'selectedBackColor set ok'); equal(options.searchResultColor, 'yellow', 'searchResultColor set ok'); equal(options.searchResultBackColor, 'darkorange', 'searchResultBackColor set ok'); - equal(options.enableLinks, true, 'enableLinks set ok'); equal(options.highlightSelected, false, 'highlightSelected set ok'); equal(options.highlightSearchResults, true, 'highlightSearchResults set ok'); equal(options.showBorder, false, 'showBorder set ok'); @@ -198,12 +195,6 @@ equal(typeof options.onSearchCleared, 'function', 'onSearchCleared set ok'); }); - test('Links enabled', function () { - init({enableLinks:true, data:data}); - ok($('.list-group-item:first').children('a').length, 'Links are enabled'); - - }); - module('Data'); @@ -296,7 +287,7 @@ // Has class node-selected ok($('.list-group-item:first').hasClass('node-selected'), 'Node is correctly selected : class "node-selected" added'); - + // Only one can be selected ok(($('.node-selected').length === 1), 'There is only one selected node'); @@ -332,13 +323,13 @@ // Has class node-selected ok(!$('.list-group-item:first').hasClass('node-selected'), 'Node is correctly unselected : class "node-selected" removed'); - + // Only one can be selected ok(($('.node-selected').length === 0), 'There are no selected nodes'); // Has correct icon ok(!options.nodeIcon || $('.expand-icon:first').hasClass(options.nodeIcon), 'Node icon is correct'); - + // Events triggered ok(cbWorked, 'onNodeUnselected function was called'); ok(onWorked, 'nodeUnselected was fired'); From ba8c555be116bfa4622587f106e3795a218e846d Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 12:27:54 +0100 Subject: [PATCH 21/52] Remove demo --- public/index.html | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/public/index.html b/public/index.html index 979ad3e3f..34474c081 100644 --- a/public/index.html +++ b/public/index.html @@ -51,18 +51,6 @@

                                                                                            Node Overrides

                                                                                            -
                                                                                            -
                                                                                            -

                                                                                            Link enabled, or

                                                                                            -
                                                                                            -
                                                                                            -
                                                                                            - -
                                                                                            -
                                                                                            - -
                                                                                            -

                                                                                            Searchable Tree

                                                                                            @@ -315,51 +303,42 @@

                                                                                            var defaultData = [ { text: 'Parent 1', - href: '#parent1', tags: ['4'], nodes: [ { text: 'Child 1', - href: '#child1', tags: ['2'], nodes: [ { text: 'Grandchild 1', - href: '#grandchild1', tags: ['0'] }, { text: 'Grandchild 2', - href: '#grandchild2', tags: ['0'] } ] }, { text: 'Child 2', - href: '#child2', tags: ['0'] } ] }, { text: 'Parent 2', - href: '#parent2', tags: ['0'] }, { text: 'Parent 3', - href: '#parent3', tags: ['0'] }, { text: 'Parent 4', - href: '#parent4', tags: ['0'] }, { text: 'Parent 5', - href: '#parent5' , tags: ['0'] } ]; @@ -396,13 +375,11 @@

                                                                                            { text: 'Parent 3', icon: 'glyphicon glyphicon-earphone', - href: '#demo', tags: ['11'] }, { text: 'Parent 4', icon: 'glyphicon glyphicon-cloud-download', - href: '/demo.html', tags: ['19'], selected: true }, @@ -411,7 +388,6 @@

                                                                                            icon: 'glyphicon glyphicon-certificate', color: 'pink', backColor: 'red', - href: 'http://www.tesco.com', tags: ['available','0'] } ]; @@ -526,12 +502,6 @@

                                                                                            data: alternateData }); - $('#treeview10').treeview({ - color: "#428bca", - enableLinks: true, - data: defaultData - }); - var $searchableTree = $('#treeview-searchable').treeview({ @@ -586,7 +556,7 @@

                                                                                            $('#chk-select-multi:checkbox').on('change', function () { console.log('multi-select change'); $selectableTree = initSelectableTree(); - selectableNodes = findSelectableNodes(); + selectableNodes = findSelectableNodes(); }); // Select/unselect/toggle nodes From cd0143aaf9ba2fdc8d59bccc6e7c111f61f5dfb8 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 12:28:16 +0100 Subject: [PATCH 22/52] Update doc to remove enableLinks and node.href usage --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index ba6ee13cf..37e1c7a0b 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,6 @@ If you want to do more, here's the full node specification selectedIcon: "glyphicon glyphicon-stop", color: "#000000", backColor: "#FFFFFF", - href: "#node-1", selectable: true, state: { checked: true, @@ -177,11 +176,6 @@ The foreground color used on a given node, overrides global color option. The background color used on a given node, overrides global color option. -#### href -`String` `Optional` - -Used in conjunction with global enableLinks option to specify anchor tag URL on a given node. - #### selectable `Boolean` `Default: true` @@ -277,11 +271,6 @@ String, class name(s). Default: "glyphicon" as defined by [Bootstrap Glyphicons Sets the icon to be used on a tree node with no child nodes. -#### enableLinks -Boolean. Default: false - -Whether or not to present node text as a hyperlink. The href value of which must be provided in the data structure on a per node basis. - #### expandIcon String, class name(s). Default: "glyphicon glyphicon-plus" as defined by [Bootstrap Glyphicons](http://getbootstrap.com/components/#glyphicons) From cef8f97f33ed63141d0cc123a90d2d3556330cc0 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 16:27:37 +0100 Subject: [PATCH 23/52] Prevent node from being unselected when option preventUnselected true --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 22 +++++++++++++++------- src/js/bootstrap-treeview.js | 22 +++++++++++++++------- tests/lib/bootstrap-treeview.js | 22 +++++++++++++++------- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 7acf91091..0ceef3536 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,f.options):-1!==e.indexOf("check-icon")?this._toggleChecked(d,f.options):d.selectable?this._toggleSelected(d,f.options):this._toggleExpanded(d,f.options)}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){return d&&c===b.state.selected?void 0:(c?(this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(a,b){this._setSelected(b,!1,d)},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))),this)},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                              ',node:'
                                                                                            • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b));else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","g","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                ',node:'
                                                                                              • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index c420b8f1c..8b427baa7 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -57,6 +57,7 @@ showCheckbox: false, showTags: false, multiSelect: false, + preventUnselect: false, // Event handlers onNodeChecked: undefined, @@ -335,16 +336,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - this._toggleExpanded(node, _default.options); + this._toggleExpanded(node, $.extend({}, _default.options)); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleChecked(node, _default.options); + this._toggleChecked(node, $.extend({}, _default.options)); } else { if (node.selectable) { - this._toggleSelected(node, _default.options); + this._toggleSelected(node, $.extend({}, _default.options)); } else { - this._toggleExpanded(node, _default.options); + this._toggleExpanded(node, $.extend({}, _default.options)); } } }; @@ -460,18 +461,18 @@ // We never pass options when rendering, so the only time // we need to validate state is from user interaction - if (options && state === node.state.selected) return; + if (options && (state === node.state.selected)) return; if (state) { // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this._setSelected(node, false, options); + this._setSelected(node, false, $.extend(options, {unselecting: true})); }, this)); } - // Set note state + // Set node state node.state.selected = true; // Set element @@ -492,6 +493,13 @@ } else { + // If preventUnselect true + only one remaining selection, disable unselect + if (this._options.preventUnselect && + (options && !options.unselecting) && + (this._findNodes('true', 'g', 'state.selected').length === 1)) { + return this; + } + // Set node state node.state.selected = false; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index c420b8f1c..8b427baa7 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -57,6 +57,7 @@ showCheckbox: false, showTags: false, multiSelect: false, + preventUnselect: false, // Event handlers onNodeChecked: undefined, @@ -335,16 +336,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - this._toggleExpanded(node, _default.options); + this._toggleExpanded(node, $.extend({}, _default.options)); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleChecked(node, _default.options); + this._toggleChecked(node, $.extend({}, _default.options)); } else { if (node.selectable) { - this._toggleSelected(node, _default.options); + this._toggleSelected(node, $.extend({}, _default.options)); } else { - this._toggleExpanded(node, _default.options); + this._toggleExpanded(node, $.extend({}, _default.options)); } } }; @@ -460,18 +461,18 @@ // We never pass options when rendering, so the only time // we need to validate state is from user interaction - if (options && state === node.state.selected) return; + if (options && (state === node.state.selected)) return; if (state) { // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this._setSelected(node, false, options); + this._setSelected(node, false, $.extend(options, {unselecting: true})); }, this)); } - // Set note state + // Set node state node.state.selected = true; // Set element @@ -492,6 +493,13 @@ } else { + // If preventUnselect true + only one remaining selection, disable unselect + if (this._options.preventUnselect && + (options && !options.unselecting) && + (this._findNodes('true', 'g', 'state.selected').length === 1)) { + return this; + } + // Set node state node.state.selected = false; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index c420b8f1c..8b427baa7 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -57,6 +57,7 @@ showCheckbox: false, showTags: false, multiSelect: false, + preventUnselect: false, // Event handlers onNodeChecked: undefined, @@ -335,16 +336,16 @@ var classList = target.attr('class') ? target.attr('class').split(' ') : []; if ((classList.indexOf('expand-icon') !== -1)) { - this._toggleExpanded(node, _default.options); + this._toggleExpanded(node, $.extend({}, _default.options)); } else if ((classList.indexOf('check-icon') !== -1)) { - this._toggleChecked(node, _default.options); + this._toggleChecked(node, $.extend({}, _default.options)); } else { if (node.selectable) { - this._toggleSelected(node, _default.options); + this._toggleSelected(node, $.extend({}, _default.options)); } else { - this._toggleExpanded(node, _default.options); + this._toggleExpanded(node, $.extend({}, _default.options)); } } }; @@ -460,18 +461,18 @@ // We never pass options when rendering, so the only time // we need to validate state is from user interaction - if (options && state === node.state.selected) return; + if (options && (state === node.state.selected)) return; if (state) { // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { - this._setSelected(node, false, options); + this._setSelected(node, false, $.extend(options, {unselecting: true})); }, this)); } - // Set note state + // Set node state node.state.selected = true; // Set element @@ -492,6 +493,13 @@ } else { + // If preventUnselect true + only one remaining selection, disable unselect + if (this._options.preventUnselect && + (options && !options.unselecting) && + (this._findNodes('true', 'g', 'state.selected').length === 1)) { + return this; + } + // Set node state node.state.selected = false; From 674060ed7c9c2a0e9b78164b5d57da36523e24f0 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 16:37:33 +0100 Subject: [PATCH 24/52] Tests --- tests/tests.js | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/tests/tests.js b/tests/tests.js index da379b492..ca3519a6e 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -110,6 +110,7 @@ equal(options.showCheckbox, false, 'showCheckbox default ok'); equal(options.showTags, false, 'showTags default ok'); equal(options.multiSelect, false, 'multiSelect default ok'); + equal(options.preventUnselect, false, 'preventUnselect default ok'); equal(options.onNodeChecked, null, 'onNodeChecked default ok'); equal(options.onNodeCollapsed, null, 'onNodeCollapsed default ok'); equal(options.onNodeDisabled, null, 'onNodeDisabled default ok'); @@ -146,6 +147,7 @@ showCheckbox: true, showTags: true, multiSelect: true, + preventUnselect: true, onNodeChecked: function () {}, onNodeCollapsed: function () {}, onNodeDisabled: function () {}, @@ -183,6 +185,7 @@ equal(options.showCheckbox, true, 'showCheckbox set ok'); equal(options.showTags, true, 'showTags set ok'); equal(options.multiSelect, true, 'multiSelect set ok'); + equal(options.preventUnselect, true, 'preventUnselect set ok'); equal(typeof options.onNodeChecked, 'function', 'onNodeChecked set ok'); equal(typeof options.onNodeCollapsed, 'function', 'onNodeCollapsed set ok'); equal(typeof options.onNodeDisabled, 'function', 'onNodeDisabled set ok'); @@ -321,10 +324,10 @@ // Simulate click $('.list-group-item:first').trigger('click'); - // Has class node-selected + // Does not have class node-selected ok(!$('.list-group-item:first').hasClass('node-selected'), 'Node is correctly unselected : class "node-selected" removed'); - // Only one can be selected + // There are no selected nodes ok(($('.node-selected').length === 0), 'There are no selected nodes'); // Has correct icon @@ -335,6 +338,41 @@ ok(onWorked, 'nodeUnselected was fired'); }); + test('Prevent a node being unselected (preventUnselect true)', function () { + var cbWorked, onWorked = false; + var $tree = init({ + data: data, + preventUnselect: true, + onNodeUnselected: function(/*event, date*/) { + cbWorked = true; + } + }) + .on('nodeUnselected', function(/*event, date*/) { + onWorked = true; + }); + var options = getOptions($tree); + + // First select a node + $('.list-group-item:first').trigger('click'); + cbWorked = onWorked = false; + + // Simulate click + $('.list-group-item:first').trigger('click'); + + // Class node-selected was not removed + ok($('.list-group-item:first').hasClass('node-selected'), 'Node was not unselected : class "node-selected" not removed'); + + // A single node remains selected + ok(($('.node-selected').length === 1), 'A single node is still selected'); + + // Has correct icon + ok(!options.nodeIcon || $('.expand-icon:first').hasClass(options.nodeIcon), 'Node icon is correct'); + + // Events where not triggered + ok(!cbWorked, 'onNodeUnselected function was not called'); + ok(!onWorked, 'nodeUnselected was not fired'); + }); + test('Selecting multiple nodes (multiSelect true)', function () { init({ From 6b1f681c5b72b119835af47ce47548b5f58c5b96 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 16:42:55 +0100 Subject: [PATCH 25/52] Update doc to include preventDefault usage --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 37e1c7a0b..f419d1179 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,11 @@ String, [any legal color value](http://www.w3schools.com/cssref/css_colors_legal Sets the default background color activated when the users cursor hovers over a node. +### preventUnselect +Boolean. Default: false + +Whether or not a node can be unselected without another node first being selected. + #### selectedIcon String, class name(s). Default: "glyphicon glyphicon-stop" as defined by [Bootstrap Glyphicons](http://getbootstrap.com/components/#glyphicons) From 5e2f3bf800734407b3e6fba68e8f79a91969f1d7 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 17:31:59 +0100 Subject: [PATCH 26/52] Fix doc formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f419d1179..e66ade66c 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,7 @@ String, [any legal color value](http://www.w3schools.com/cssref/css_colors_legal Sets the default background color activated when the users cursor hovers over a node. -### preventUnselect +#### preventUnselect Boolean. Default: false Whether or not a node can be unselected without another node first being selected. From 0d57ff5a818f2808cd217e74487aa818c4a544a0 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 17:45:03 +0100 Subject: [PATCH 27/52] Documented proposed method --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index e66ade66c..6094056fc 100644 --- a/README.md +++ b/README.md @@ -507,12 +507,20 @@ $('#tree').treeview('expandNode', [ nodeId, { levels: 2, silent: true } ]); Triggers `nodeExpanded` event; pass silent to suppress events. +#### findNodes(pattern, field) + +Returns an array of matching node objects. + +```javascript +$('#tree').treeview('findNode', ['Parent', 'text']); +``` + #### getChecked() Returns an array of checked nodes e.g. state.checked = true. ```javascript -$('#tree').treeview('getChecked', nodeId); +$('#tree').treeview('getChecked'); ``` #### getCollapsed() @@ -520,7 +528,7 @@ $('#tree').treeview('getChecked', nodeId); Returns an array of collapsed nodes e.g. state.expanded = false. ```javascript -$('#tree').treeview('getCollapsed', nodeId); +$('#tree').treeview('getCollapsed'); ``` #### getDisabled() @@ -528,7 +536,7 @@ $('#tree').treeview('getCollapsed', nodeId); Returns an array of disabled nodes e.g. state.disabled = true. ```javascript -$('#tree').treeview('getDisabled', nodeId); +$('#tree').treeview('getDisabled'); ``` #### getEnabled() @@ -536,7 +544,7 @@ $('#tree').treeview('getDisabled', nodeId); Returns an array of enabled nodes e.g. state.disabled = false. ```javascript -$('#tree').treeview('getEnabled', nodeId); +$('#tree').treeview('getEnabled'); ``` #### getExpanded() @@ -544,15 +552,7 @@ $('#tree').treeview('getEnabled', nodeId); Returns an array of expanded nodes e.g. state.expanded = true. ```javascript -$('#tree').treeview('getExpanded', nodeId); -``` - -#### getNode(nodeId) - -Returns a single node object that matches the given node id. - -```javascript -$('#tree').treeview('getNode', nodeId); +$('#tree').treeview('getExpanded'); ``` #### getParent(node | nodeId) @@ -568,7 +568,7 @@ $('#tree').treeview('getParent', node); Returns an array of selected nodes e.g. state.selected = true. ```javascript -$('#tree').treeview('getSelected', nodeId); +$('#tree').treeview('getSelected'); ``` #### getSiblings(node | nodeId) @@ -584,7 +584,7 @@ $('#tree').treeview('getSiblings', node); Returns an array of unchecked nodes e.g. state.checked = false. ```javascript -$('#tree').treeview('getUnchecked', nodeId); +$('#tree').treeview('getUnchecked'); ``` #### getUnselected() @@ -592,7 +592,7 @@ $('#tree').treeview('getUnchecked', nodeId); Returns an array of unselected nodes e.g. state.selected = false. ```javascript -$('#tree').treeview('getUnselected', nodeId); +$('#tree').treeview('getUnselected'); ``` #### remove() From 663fdfe79bec3dd686742d43512564675c338591 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 22 May 2016 20:28:38 +0100 Subject: [PATCH 28/52] Refactor node query logic - Replaced getNode() with findNodes() which allows querying of nodes by any value - Replaced getParent() with getParents() which accepts multiple nodes (array) --- README.md | 12 +- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 70 ++++++--- src/js/bootstrap-treeview.js | 56 ++++--- tests/lib/bootstrap-treeview.js | 70 ++++++--- tests/tests.js | 264 ++++++++++++-------------------- 6 files changed, 232 insertions(+), 242 deletions(-) diff --git a/README.md b/README.md index 6094056fc..318a17d95 100644 --- a/README.md +++ b/README.md @@ -555,12 +555,12 @@ Returns an array of expanded nodes e.g. state.expanded = true. $('#tree').treeview('getExpanded'); ``` -#### getParent(node | nodeId) +#### getParents(nodes) -Returns the parent node of a given node, if valid otherwise returns undefined. +Returns parent nodes for given nodes, if valid otherwise returns undefined. ```javascript -$('#tree').treeview('getParent', node); +$('#tree').treeview('getParent', nodes); ``` #### getSelected() @@ -571,12 +571,12 @@ Returns an array of selected nodes e.g. state.selected = true. $('#tree').treeview('getSelected'); ``` -#### getSiblings(node | nodeId) +#### getSiblings(nodes) -Returns an array of sibling nodes for a given node, if valid otherwise returns undefined. +Returns an array of sibling nodes for given nodes, if valid otherwise returns undefined. ```javascript -$('#tree').treeview('getSiblings', node); +$('#tree').treeview('getSiblings', nodes); ``` #### getUnchecked() diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 0ceef3536..f1ae9d05c 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b));else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","g","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                  ',node:'
                                                                                                • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this._nodes[a]},g.prototype.getParent=function(a){var b=this._identifyNode(a);return this._nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this._identifyNode(a),c=this.getParent(b),d=c?c.nodes:this._tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParent(d);)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b));else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","g","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                    ',node:'
                                                                                                  • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,"g",b)},g.prototype.getParents=function(b){var c=[];return console.log("getParents nodes = ",b),a.each(b,a.proxy(function(a,b){console.log("getParents node = ",a,b),c.push(this._nodes[b.parentId])},this)),console.log("getParenst [] = ",c),c},g.prototype.getSiblings=function(b){console.log("getSiblings nodes = ",b);var c=[];return a.each(b,a.proxy(function(a,b){console.log("getSiblings node =",b);var d=this.getParents([b]);console.log("getSiblings parent = ",d);var e=d[0]?d[0].nodes:this._tree;console.log("getSiblings nodes 2 = ",e),e&&c.push(e.filter(function(a){return console.log("** match ",a.nodeId,b.nodeId),a.nodeId!==b.nodeId}))},this)),console.log("getSiblings siblingNodes = ",c),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParents([d])[0];)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return console.log("_identifyNode ",a),"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return console.log("_findNode val = ",d,e),"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 8b427baa7..a26afa9e0 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -101,8 +101,8 @@ remove: $.proxy(this._remove, this), // Get methods - getNode: $.proxy(this.getNode, this), - getParent: $.proxy(this.getParent, this), + findNodes: $.proxy(this.findNodes, this), + getParents: $.proxy(this.getParents, this), getSiblings: $.proxy(this.getSiblings, this), getSelected: $.proxy(this.getSelected, this), getUnselected: $.proxy(this.getUnselected, this), @@ -857,36 +857,56 @@ /** - Returns a single node object that matches the given node id. - @param {Number} nodeId - A node's unique identifier - @return {Object} node - Matching node + Returns an array of matching node objects. + @param {Number|String|Boolean|Undefined|Null} pattern - A pattern to match against a given field + @return {String} field - Field to query pattern against */ - Tree.prototype.getNode = function (nodeId) { - return this._nodes[nodeId]; + Tree.prototype.findNodes = function (pattern, field) { + return this._findNodes(pattern, 'g', field); }; /** - Returns the parent node of a given node, if valid otherwise returns undefined. - @param {Object|Number} identifier - A valid node or node id - @returns {Object} node - The parent node + Returns parent nodes for given nodes, if valid otherwise returns undefined. + @param {Array} nodes - An array of nodes + @returns {Array} nodes - An array of parent nodes */ - Tree.prototype.getParent = function (identifier) { - var node = this._identifyNode(identifier); - return this._nodes[node.parentId]; + Tree.prototype.getParents = function (nodes) { + var parentNodes = []; + console.log('getParents nodes = ', nodes); + $.each(nodes, $.proxy(function (index, node) { + console.log('getParents node = ', index, node); + parentNodes.push(this._nodes[node.parentId]); + }, this)); + console.log('getParenst [] = ', parentNodes); + return parentNodes; }; /** - Returns an array of sibling nodes for a given node, if valid otherwise returns undefined. - @param {Object|Number} identifier - A valid node or node id - @returns {Array} nodes - Sibling nodes + Returns an array of sibling nodes for given nodes, if valid otherwise returns undefined. + @param {Array} nodes - An array of nodes + @returns {Array} nodes - An array of sibling nodes */ - Tree.prototype.getSiblings = function (identifier) { - var node = this._identifyNode(identifier); - var parent = this.getParent(node); - var nodes = parent ? parent.nodes : this._tree; - return nodes.filter(function (obj) { - return obj.nodeId !== node.nodeId; - }); + Tree.prototype.getSiblings = function (nodes) { + console.log('getSiblings nodes = ', nodes); + var siblingNodes = []; + $.each(nodes, $.proxy(function (index, node) { + console.log('getSiblings node =', node); + var parent = this.getParents([node]); + console.log('getSiblings parent = ', parent); + var nodes = parent[0] ? parent[0].nodes : this._tree; + console.log('getSiblings nodes 2 = ', nodes); + if (nodes) { + siblingNodes.push(nodes.filter(function (obj) { + console.log('** match ', obj.nodeId, node.nodeId); + return obj.nodeId !== node.nodeId; + }) + ); + } + }, this)); + console.log('getSiblings siblingNodes = ', siblingNodes); + return $.map(siblingNodes, function (obj) { + return obj; + }); }; /** @@ -1051,7 +1071,7 @@ this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { var parentNode = node; var tmpNode; - while (tmpNode = this.getParent(parentNode)) { + while (tmpNode = this.getParents([parentNode])[0]) { parentNode = tmpNode; this._setExpanded(parentNode, true, options); }; @@ -1202,6 +1222,7 @@ Identifies a node from either a node id or object */ Tree.prototype._identifyNode = function (identifier) { + console.log('_identifyNode ', identifier); return ((typeof identifier) === 'number') ? this._nodes[identifier] : identifier; @@ -1295,6 +1316,7 @@ return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); + console.log('_findNode val = ', attribute, val); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 8b427baa7..fa6f5aaed 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -101,8 +101,8 @@ remove: $.proxy(this._remove, this), // Get methods - getNode: $.proxy(this.getNode, this), - getParent: $.proxy(this.getParent, this), + findNodes: $.proxy(this.findNodes, this), + getParents: $.proxy(this.getParents, this), getSiblings: $.proxy(this.getSiblings, this), getSelected: $.proxy(this.getSelected, this), getUnselected: $.proxy(this.getUnselected, this), @@ -857,36 +857,44 @@ /** - Returns a single node object that matches the given node id. - @param {Number} nodeId - A node's unique identifier - @return {Object} node - Matching node + Returns an array of matching node objects. + @param {Number|String|Boolean|Undefined|Null} pattern - A pattern to match against a given field + @return {String} field - Field to query pattern against */ - Tree.prototype.getNode = function (nodeId) { - return this._nodes[nodeId]; + Tree.prototype.findNodes = function (pattern, field) { + return this._findNodes(pattern, 'g', field); }; /** - Returns the parent node of a given node, if valid otherwise returns undefined. - @param {Object|Number} identifier - A valid node or node id - @returns {Object} node - The parent node + Returns parent nodes for given nodes, if valid otherwise returns undefined. + @param {Array} nodes - An array of nodes + @returns {Array} nodes - An array of parent nodes */ - Tree.prototype.getParent = function (identifier) { - var node = this._identifyNode(identifier); - return this._nodes[node.parentId]; + Tree.prototype.getParents = function (nodes) { + var parentNodes = []; + $.each(nodes, $.proxy(function (index, node) { + parentNodes.push(this._nodes[node.parentId]); + }, this)); + return parentNodes; }; /** - Returns an array of sibling nodes for a given node, if valid otherwise returns undefined. - @param {Object|Number} identifier - A valid node or node id - @returns {Array} nodes - Sibling nodes + Returns an array of sibling nodes for given nodes, if valid otherwise returns undefined. + @param {Array} nodes - An array of nodes + @returns {Array} nodes - An array of sibling nodes */ - Tree.prototype.getSiblings = function (identifier) { - var node = this._identifyNode(identifier); - var parent = this.getParent(node); - var nodes = parent ? parent.nodes : this._tree; - return nodes.filter(function (obj) { - return obj.nodeId !== node.nodeId; - }); + Tree.prototype.getSiblings = function (nodes) { + return $.map( + $.each(nodes, $.proxy(function (index, node) { + var parent = this.getParents([node]); + var nodes = parent[0] ? parent[0].nodes : this._tree; + return nodes.filter(function (obj) { + return obj.nodeId !== node.nodeId; + }); + }, this), function (obj) { + return obj; + } + ); }; /** @@ -1051,7 +1059,7 @@ this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { var parentNode = node; var tmpNode; - while (tmpNode = this.getParent(parentNode)) { + while (tmpNode = this.getParents([parentNode])[0]) { parentNode = tmpNode; this._setExpanded(parentNode, true, options); }; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 8b427baa7..a26afa9e0 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -101,8 +101,8 @@ remove: $.proxy(this._remove, this), // Get methods - getNode: $.proxy(this.getNode, this), - getParent: $.proxy(this.getParent, this), + findNodes: $.proxy(this.findNodes, this), + getParents: $.proxy(this.getParents, this), getSiblings: $.proxy(this.getSiblings, this), getSelected: $.proxy(this.getSelected, this), getUnselected: $.proxy(this.getUnselected, this), @@ -857,36 +857,56 @@ /** - Returns a single node object that matches the given node id. - @param {Number} nodeId - A node's unique identifier - @return {Object} node - Matching node + Returns an array of matching node objects. + @param {Number|String|Boolean|Undefined|Null} pattern - A pattern to match against a given field + @return {String} field - Field to query pattern against */ - Tree.prototype.getNode = function (nodeId) { - return this._nodes[nodeId]; + Tree.prototype.findNodes = function (pattern, field) { + return this._findNodes(pattern, 'g', field); }; /** - Returns the parent node of a given node, if valid otherwise returns undefined. - @param {Object|Number} identifier - A valid node or node id - @returns {Object} node - The parent node + Returns parent nodes for given nodes, if valid otherwise returns undefined. + @param {Array} nodes - An array of nodes + @returns {Array} nodes - An array of parent nodes */ - Tree.prototype.getParent = function (identifier) { - var node = this._identifyNode(identifier); - return this._nodes[node.parentId]; + Tree.prototype.getParents = function (nodes) { + var parentNodes = []; + console.log('getParents nodes = ', nodes); + $.each(nodes, $.proxy(function (index, node) { + console.log('getParents node = ', index, node); + parentNodes.push(this._nodes[node.parentId]); + }, this)); + console.log('getParenst [] = ', parentNodes); + return parentNodes; }; /** - Returns an array of sibling nodes for a given node, if valid otherwise returns undefined. - @param {Object|Number} identifier - A valid node or node id - @returns {Array} nodes - Sibling nodes + Returns an array of sibling nodes for given nodes, if valid otherwise returns undefined. + @param {Array} nodes - An array of nodes + @returns {Array} nodes - An array of sibling nodes */ - Tree.prototype.getSiblings = function (identifier) { - var node = this._identifyNode(identifier); - var parent = this.getParent(node); - var nodes = parent ? parent.nodes : this._tree; - return nodes.filter(function (obj) { - return obj.nodeId !== node.nodeId; - }); + Tree.prototype.getSiblings = function (nodes) { + console.log('getSiblings nodes = ', nodes); + var siblingNodes = []; + $.each(nodes, $.proxy(function (index, node) { + console.log('getSiblings node =', node); + var parent = this.getParents([node]); + console.log('getSiblings parent = ', parent); + var nodes = parent[0] ? parent[0].nodes : this._tree; + console.log('getSiblings nodes 2 = ', nodes); + if (nodes) { + siblingNodes.push(nodes.filter(function (obj) { + console.log('** match ', obj.nodeId, node.nodeId); + return obj.nodeId !== node.nodeId; + }) + ); + } + }, this)); + console.log('getSiblings siblingNodes = ', siblingNodes); + return $.map(siblingNodes, function (obj) { + return obj; + }); }; /** @@ -1051,7 +1071,7 @@ this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { var parentNode = node; var tmpNode; - while (tmpNode = this.getParent(parentNode)) { + while (tmpNode = this.getParents([parentNode])[0]) { parentNode = tmpNode; this._setExpanded(parentNode, true, options); }; @@ -1202,6 +1222,7 @@ Identifies a node from either a node id or object */ Tree.prototype._identifyNode = function (identifier) { + console.log('_identifyNode ', identifier); return ((typeof identifier) === 'number') ? this._nodes[identifier] : identifier; @@ -1295,6 +1316,7 @@ return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); + console.log('_findNode val = ', attribute, val); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } diff --git a/tests/tests.js b/tests/tests.js index ca3519a6e..72d946462 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -506,25 +506,25 @@ module('Methods'); - test('getNode', function () { - var $tree = init({ data: data }); - var nodeParent1 = $tree.treeview('getNode', 0); + test('findNodes', function () { + var tree = init({ data: data }).treeview(true); + var nodeParent1 = tree.findNodes('Parent 1', 'text')[0]; equal(nodeParent1.text, 'Parent 1', 'Correct node returned : requested "Parent 1", got "Parent 1"'); }); - test('getParent', function () { - var $tree = init({ data: data }); - var nodeChild1 = $tree.treeview('getNode', 1); - var parentNode = $tree.treeview('getParent', nodeChild1); + test('getParents', function () { + var tree = init({ data: data }).treeview(true); + var nodeChild1 = tree.findNodes('Child 1', 'text'); + var parentNode = tree.getParents(nodeChild1)[0]; equal(parentNode.text, 'Parent 1', 'Correct node returned : requested parent of "Child 1", got "Parent 1"'); }); test('getSiblings', function () { - var $tree = init({ data: data }); + var tree = init({ data: data }).treeview(true); // Test root level, internally uses the this.tree - var nodeParent1 = $tree.treeview('getNode', 0); - var nodeParent1Siblings = $tree.treeview('getSiblings', nodeParent1); + var nodeParent1 = tree.findNodes('Parent 1', 'text'); + var nodeParent1Siblings = tree.getSiblings(nodeParent1); var isArray = (nodeParent1Siblings instanceof Array); var countOK = nodeParent1Siblings.length === 4; var resultsOK = nodeParent1Siblings[0].text === 'Parent 2'; @@ -536,8 +536,8 @@ ok(resultsOK, 'Correct siblings for "Parent 1" [root] : results OK'); // Test non root level, internally uses getParent.nodes - var nodeChild1 = $tree.treeview('getNode', 1); - var nodeChild1Siblings = $tree.treeview('getSiblings', nodeChild1); + var nodeChild1 = tree.findNodes('Child 1', 'text'); + var nodeChild1Siblings = tree.getSiblings(nodeChild1); var isArray = (nodeChild1Siblings instanceof Array); var countOK = nodeChild1Siblings.length === 1; var results = nodeChild1Siblings[0].text === 'Child 2' @@ -627,221 +627,157 @@ test('disableAll / enableAll', function () { var $tree = init({ data: data, levels: 1 }); + var tree = $tree.treeview(true); - $tree.treeview('disableAll'); + tree.disableAll(); equal($($tree.selector + ' ul li:not(.node-hidden).node-disabled').length, 5, 'Disable all works, 9 nodes with node-disabled class'); - $tree.treeview('enableAll'); + tree.enableAll(); equal($($tree.selector + ' ul li:not(.node-hidden).node-disabled').length, 0, 'Check all works, 9 nodes non with node-disabled class'); }); test('disableNode / enableNode', function () { - var $tree = init({ data: data, levels: 1 }); - var nodeId = 0; - var node = $tree.treeview('getNode', 0); - - // Disable node using node id - $tree.treeview('disableNode', nodeId); - ok($('.list-group-item:first').hasClass('node-disabled'), 'Disable node (by id) : Node has class node-disabled'); - ok(($('.node-disabled').length === 1), 'Disable node (by id) : There is only one disabled node'); - - // Enable node using node id - $tree.treeview('enableNode', nodeId); - ok(!$('.list-group-item:first').hasClass('node-disabled'), 'Enable node (by id) : Node does not have class node-disabled'); - ok(($('.node-checked').length === 0), 'Enable node (by id) : There are no disabled nodes'); + var tree = init({ data: data, levels: 1 }).treeview(true); + var node = tree.findNodes('Parent 1', 'text'); - // Disable node using node - $tree.treeview('disableNode', node); - ok($('.list-group-item:first').hasClass('node-disabled'), 'Disable node (by node) : Node has class node-disabled'); - ok(($('.node-disabled').length === 1), 'Disable node (by node) : There is only one disabled node'); + tree.disableNode(node); + ok($('.list-group-item:first').hasClass('node-disabled'), 'Disable node : Node has class node-disabled'); + ok(($('.node-disabled').length === 1), 'Disable node : There is only one disabled node'); - // Enable node using node - $tree.treeview('enableNode', node); - ok(!$('.list-group-item:first').hasClass('node-disabled'), 'Enable node (by node) : Node does not have class node-disabled'); - ok(($('.node-checked').length === 0), 'Enable node (by node) : There are no disabled nodes'); + tree.enableNode(node); + ok(!$('.list-group-item:first').hasClass('node-disabled'), 'Enable node : Node does not have class node-disabled'); + ok(($('.node-checked').length === 0), 'Enable node : There are no disabled nodes'); }); test('toggleNodeDisabled', function () { - var $tree = init({ data: data, levels: 1 }); - var nodeId = 0; - var node = $tree.treeview('getNode', 0); + var tree = init({ data: data, levels: 1 }).treeview(true); + var node = tree.findNodes('Parent 1', 'text'); - // Toggle disabled using node id - $tree.treeview('toggleNodeDisabled', nodeId); - ok($('.list-group-item:first').hasClass('node-disabled'), 'Toggle node (by id) : Node has class node-disabled'); - ok(($('.node-disabled').length === 1), 'Toggle node (by id) : There is only one disabled node'); + tree.toggleNodeDisabled(node); + ok($('.list-group-item:first').hasClass('node-disabled'), 'Toggle node : Node has class node-disabled'); + ok(($('.node-disabled').length === 1), 'Toggle node : There is only one disabled node'); - // Toggle disabled using node - $tree.treeview('toggleNodeDisabled', node); - ok(!$('.list-group-item:first').hasClass('node-disabled'), 'Toggle node (by node) : Node does not have class node-disabled'); - ok(($('.node-disabled').length === 0), 'Toggle node (by node) : There are no disabled nodes'); + tree.toggleNodeDisabled(node); + ok(!$('.list-group-item:first').hasClass('node-disabled'), 'Toggle node : Node does not have class node-disabled'); + ok(($('.node-disabled').length === 0), 'Toggle node : There are no disabled nodes'); }); test('checkAll / uncheckAll', function () { var $tree = init({ data: data, levels: 3, showCheckbox: true }); + var tree = $tree.treeview(true); - $tree.treeview('checkAll'); + tree.checkAll(); equal($($tree.selector + ' ul li.node-checked').length, 9, 'Check all works, 9 nodes with node-checked class'); equal($($tree.selector + ' ul li .glyphicon-check').length, 9, 'Check all works, 9 nodes with glyphicon-check icon'); - $tree.treeview('uncheckAll'); + tree.uncheckAll(); equal($($tree.selector + ' ul li.node-checked').length, 0, 'Check all works, 9 nodes non with node-checked class'); equal($($tree.selector + ' ul li .glyphicon-unchecked').length, 9, 'Check all works, 9 nodes with glyphicon-unchecked icon'); }); test('checkNode / uncheckNode', function () { - var $tree = init({ data: data, showCheckbox: true }); - var options = getOptions($tree); - var nodeId = 0; - var node = $tree.treeview('getNode', 0); - - // Check node using node id - $tree.treeview('checkNode', nodeId); - ok($('.list-group-item:first').hasClass('node-checked'), 'Check node (by id) : Node has class node-checked'); - ok(($('.node-checked').length === 1), 'Check node (by id) : There is only one checked node'); - ok($('.check-icon:first').hasClass(options.checkedIcon), 'Check node (by id) : Node icon is correct'); - - // Uncheck node using node id - $tree.treeview('uncheckNode', nodeId); - ok(!$('.list-group-item:first').hasClass('node-checked'), 'Uncheck node (by id) : Node does not have class node-checked'); - ok(($('.node-checked').length === 0), 'Uncheck node (by id) : There are no checked nodes'); - ok($('.check-icon:first').hasClass(options.uncheckedIcon), 'Uncheck node (by id) : Node icon is correct'); - - // Check node using node - $tree.treeview('checkNode', node); - ok($('.list-group-item:first').hasClass('node-checked'), 'Check node (by node) : Node has class node-checked'); - ok(($('.node-checked').length === 1), 'Check node (by node) : There is only one checked node'); - ok($('.check-icon:first').hasClass(options.checkedIcon), 'Check node (by node) : Node icon is correct'); - - // Uncheck node using node - $tree.treeview('uncheckNode', node); - ok(!$('.list-group-item:first').hasClass('node-checked'), 'Uncheck node (by node) : Node does not have class node-checked'); - ok(($('.node-checked').length === 0), 'Uncheck node (by node) : There are no checked nodes'); - ok($('.check-icon:first').hasClass(options.uncheckedIcon), 'Uncheck node (by node) : Node icon is correct'); + var tree = init({ data: data, showCheckbox: true }).treeview(true); + var node = tree.findNodes('Parent 1', 'text'); + + tree.checkNode(node); + ok($('.list-group-item:first').hasClass('node-checked'), 'Check node : Node has class node-checked'); + ok(($('.node-checked').length === 1), 'Check node : There is only one checked node'); + ok($('.check-icon:first').hasClass(tree.options.checkedIcon), 'Check node : Node icon is correct'); + + tree.uncheckNode(node); + ok(!$('.list-group-item:first').hasClass('node-checked'), 'Uncheck node : Node does not have class node-checked'); + ok(($('.node-checked').length === 0), 'Uncheck node : There are no checked nodes'); + ok($('.check-icon:first').hasClass(tree.options.uncheckedIcon), 'Uncheck node : Node icon is correct'); }); test('toggleNodeChecked', function () { - var $tree = init({ data: data, showCheckbox: true }); - var options = getOptions($tree); - var nodeId = 0; - var node = $tree.treeview('getNode', 0); + var tree = init({ data: data, showCheckbox: true }).treeview(true); + var node = tree.findNodes('Parent 1', 'text'); - // Toggle checked using node id - $tree.treeview('toggleNodeChecked', nodeId); - ok($('.list-group-item:first').hasClass('node-checked'), 'Toggle node (by id) : Node has class node-checked'); - ok(($('.node-checked').length === 1), 'Toggle node (by id) : There is only one checked node'); - ok($('.check-icon:first').hasClass(options.checkedIcon), 'Toggle node (by id) : Node icon is correct'); + tree.toggleNodeChecked(node); + ok($('.list-group-item:first').hasClass('node-checked'), 'Toggle node : Node has class node-checked'); + ok(($('.node-checked').length === 1), 'Toggle node : There is only one checked node'); + ok($('.check-icon:first').hasClass(tree.options.checkedIcon), 'Toggle node : Node icon is correct'); - // Toggle checked using node - $tree.treeview('toggleNodeChecked', node); - ok(!$('.list-group-item:first').hasClass('node-checked'), 'Toggle node (by node) : Node does not have class node-checked'); - ok(($('.node-checked').length === 0), 'Toggle node (by node) : There are no checked nodes'); - ok($('.check-icon:first').hasClass(options.uncheckedIcon), 'Toggle node (by node) : Node icon is correct'); + tree.toggleNodeChecked(node); + ok(!$('.list-group-item:first').hasClass('node-checked'), 'Toggle node : Node does not have class node-checked'); + ok(($('.node-checked').length === 0), 'Toggle node : There are no checked nodes'); + ok($('.check-icon:first').hasClass(tree.options.uncheckedIcon), 'Toggle node : Node icon is correct'); }); test('selectNode / unselectNode', function () { - var $tree = init({ data: data, selectedIcon: 'glyphicon glyphicon-selected' }); - var nodeId = 0; - var node = $tree.treeview('getNode', 0); + var tree = init({ data: data, selectedIcon: 'glyphicon glyphicon-selected' }).treeview(true); + var node = tree.findNodes('Parent 1', 'text'); - // Select node using node id - $tree.treeview('selectNode', nodeId); - ok($('.list-group-item:first').hasClass('node-selected'), 'Select node (by id) : Node has class node-selected'); - ok(($('.node-selected').length === 1), 'Select node (by id) : There is only one selected node'); + tree.selectNode(node); + ok($('.list-group-item:first').hasClass('node-selected'), 'Select node : Node has class node-selected'); + ok(($('.node-selected').length === 1), 'Select node : There is only one selected node'); - // Unselect node using node id - $tree.treeview('unselectNode', nodeId); - ok(!$('.list-group-item:first').hasClass('node-selected'), 'Unselect node (by id) : Node does not have class node-selected'); - ok(($('.node-selected').length === 0), 'Unselect node (by id) : There are no selected nodes'); - - // Select node using node - $tree.treeview('selectNode', node); - ok($('.list-group-item:first').hasClass('node-selected'), 'Select node (by node) : Node has class node-selected'); - ok(($('.node-selected').length === 1), 'Select node (by node) : There is only one selected node'); - - // Unselect node using node id - $tree.treeview('unselectNode', node); - ok(!$('.list-group-item:first').hasClass('node-selected'), 'Unselect node (by node) : Node does not have class node-selected'); - ok(($('.node-selected').length === 0), 'Unselect node (by node) : There are no selected nodes'); + tree.unselectNode(node); + ok(!$('.list-group-item:first').hasClass('node-selected'), 'Unselect node : Node does not have class node-selected'); + ok(($('.node-selected').length === 0), 'Unselect node : There are no selected nodes'); }); test('toggleNodeSelected', function () { - var $tree = init({ data: data }); - var nodeId = 0; - var node = $tree.treeview('getNode', 0); + var tree = init({ data: data }).treeview(true); + var node = tree.findNodes('Parent 1', 'text'); - // Toggle selected using node id - $tree.treeview('toggleNodeSelected', nodeId); - ok($('.list-group-item:first').hasClass('node-selected'), 'Toggle node (by id) : Node has class node-selected'); - ok(($('.node-selected').length === 1), 'Toggle node (by id) : There is only one selected node'); + tree.toggleNodeSelected(node); + ok($('.list-group-item:first').hasClass('node-selected'), 'Toggle node : Node has class node-selected'); + ok(($('.node-selected').length === 1), 'Toggle node : There is only one selected node'); - // Toggle selected using node - $tree.treeview('toggleNodeSelected', node); - ok(!$('.list-group-item:first').hasClass('node-selected'), 'Toggle node (by id) : Node does not have class node-selected'); - ok(($('.node-selected').length === 0), 'Toggle node (by node) : There are no selected nodes'); + tree.toggleNodeSelected(node); + ok(!$('.list-group-item:first').hasClass('node-selected'), 'Toggle node : Node does not have class node-selected'); + ok(($('.node-selected').length === 0), 'Toggle node : There are no selected nodes'); }); test('expandAll / collapseAll', function () { var $tree = init({ data: data, levels: 1 }); + var tree = $tree.treeview(true); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Starts in collapsed state, 5 root nodes displayed'); - $tree.treeview('expandAll'); + tree.expandAll(); equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Expand all works, all 9 nodes displayed'); - $tree.treeview('collapseAll'); + tree.collapseAll(); equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse all works, 5 original root nodes displayed'); - $tree.treeview('expandAll', { levels: 1 }); + tree.expandAll({ levels: 1 }); equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand all (levels = 1) works, correctly displayed 7 nodes'); }); test('expandNode / collapseNode / toggleExpanded', function () { var $tree = init({ data: data, levels: 1 }); + var tree = $tree.treeview(true); + var node = tree.findNodes('Parent 1', 'text'); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Starts in collapsed state, 5 root nodes displayed'); - $tree.treeview('expandNode', 0); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand node (by id) works, 7 nodes displayed'); + tree.expandNode(node); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand node works, 7 nodes displayed'); - $tree.treeview('collapseNode', 0); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse node (by id) works, 5 original nodes displayed'); + tree.collapseNode(node); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse node works, 5 original nodes displayed'); - $tree.treeview('toggleNodeExpanded', 0); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Toggle node (by id) works, 7 nodes displayed'); + tree.toggleNodeExpanded(node); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Toggle node works, 7 nodes displayed'); - $tree.treeview('toggleNodeExpanded', 0); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Toggle node (by id) works, 5 original nodes displayed'); + tree.toggleNodeExpanded(node); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Toggle node works, 5 original nodes displayed'); - $tree.treeview('expandNode', [ 0, { levels: 2 } ]); + tree.expandNode(node, { levels: 2 }); equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Expand node (levels = 2, by id) works, 9 nodes displayed'); - - $tree = init({ data: data, levels: 1 }); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Reset to collapsed state, 5 root nodes displayed'); - - var nodeParent1 = $tree.treeview('getNode', 0); - $tree.treeview('expandNode', nodeParent1); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Expand node (by node) works, 7 nodes displayed'); - - $tree.treeview('collapseNode', nodeParent1); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Collapse node (by node) works, 5 original nodes displayed'); - - $tree.treeview('toggleNodeExpanded', nodeParent1); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Toggle node (by node) works, 7 nodes displayed'); - - $tree.treeview('toggleNodeExpanded', nodeParent1); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 5, 'Toggle node (by node) works, 5 original nodes displayed'); - - $tree.treeview('expandNode', [ nodeParent1, { levels: 2 } ]); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Expand node (levels = 2, by node) works, 9 nodes displayed'); }); test('revealNode', function () { var $tree = init({ data: data, levels: 1 }); + var tree = $tree.treeview(true); - $tree.treeview('revealNode', 1); // Child_1 - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Reveal node (by id) works, reveal Child 1 and 7 nodes displayed'); + tree.revealNode(tree.findNodes('Child 1', 'text')); + equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Reveal node works, reveal Child 1 and 7 nodes displayed'); - var nodeGrandchild1 = $tree.treeview('getNode', 2); // Grandchild 1 - $tree.treeview('revealNode', nodeGrandchild1); + $tree.treeview('revealNode', tree.findNodes('Grandchild 1', 'text')); equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Reveal node (by node) works, reveal Grandchild 1 and 9 nodes displayed'); }); @@ -856,21 +792,22 @@ .on('searchComplete', function(/*event, results*/) { onWorked = true; }); + var tree = $tree.treeview(true); // Case sensitive, exact match - var result = $tree.treeview('search', [ 'Parent 1', { ignoreCase: false, exactMatch: true } ]); + var result = tree.search('Parent 1', { ignoreCase: false, exactMatch: true }); equal(result.length, 1, 'Search "Parent 1" case sensitive, exact match - returns 1 result'); // Case sensitive, like - result = $tree.treeview('search', [ 'Parent', { ignoreCase: false, exactMatch: false } ]); + result = tree.search('Parent', { ignoreCase: false, exactMatch: false }); equal(result.length, 5, 'Search "Parent" case sensitive, exact match - returns 5 results'); // Case insensitive, exact match - result = $tree.treeview('search', [ 'parent 1', { ignoreCase: true, exactMatch: true } ]); + result = tree.search('parent 1', { ignoreCase: true, exactMatch: true }); equal(result.length, 1, 'Search "parent 1" case insensitive, exact match - returns 1 result'); // Case insensitive, like - result = $tree.treeview('search', [ 'parent', { ignoreCase: true, exactMatch: false } ]); + result = tree.search('parent', { ignoreCase: true, exactMatch: false }); equal(result.length, 5, 'Search "parent" case insensitive, exact match - returns 5 results') // Check events fire @@ -889,11 +826,12 @@ .on('searchCleared', function(/*event, results*/) { onWorked = true; }); + var tree = $tree.treeview(true); // Check results are cleared - $tree.treeview('search', [ 'Parent 1', { ignoreCase: false, exactMatch: true } ]); + tree.search('Parent 1', { ignoreCase: false, exactMatch: true }); equal($tree.find('.node-result').length, 1, 'Search results highlighted'); - $tree.treeview('clearSearch'); + tree.clearSearch(); equal($tree.find('.node-result').length, 0, 'Search results cleared'); // Check events fire From 2fbdafcdd8a72f20a41d530e3bc10d38ac5cb670 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Mon, 23 May 2016 20:11:53 +0100 Subject: [PATCH 29/52] Simplified all methods to accept only nodes (Array of node objects) instead of optional identifiers (confusing) --- README.md | 74 +++++------ dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 215 ++++++++++++++----------------- src/js/bootstrap-treeview.js | 217 ++++++++++++++++---------------- tests/lib/bootstrap-treeview.js | 215 ++++++++++++++----------------- tests/tests.js | 47 ++++--- 6 files changed, 359 insertions(+), 411 deletions(-) diff --git a/README.md b/README.md index 318a17d95..0e34b680b 100644 --- a/README.md +++ b/README.md @@ -407,12 +407,12 @@ $('#tree').treeview('checkAll', { silent: true }); Triggers `nodeChecked` event; pass silent to suppress events. -#### checkNode(node | nodeId, options) +#### checkNode(nodes, options) -Checks a given tree node, accepts node or nodeId. +Checks given tree nodes. ```javascript -$('#tree').treeview('checkNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('checkNode', [ nodes, { silent: true } ]); ``` Triggers `nodeChecked` event; pass silent to suppress events. @@ -437,12 +437,12 @@ $('#tree').treeview('collapseAll', { silent: true }); Triggers `nodeCollapsed` event; pass silent to suppress events. -#### collapseNode(node | nodeId, options) +#### collapseNode(nodes, options) Collapse a given tree node and it's child nodes. If you don't want to collapse the child nodes, pass option `{ ignoreChildren: true }`. ```javascript -$('#tree').treeview('collapseNode', [ nodeId, { silent: true, ignoreChildren: false } ]); +$('#tree').treeview('collapseNode', [ nodes, { silent: true, ignoreChildren: false } ]); ``` Triggers `nodeCollapsed` event; pass silent to suppress events. @@ -457,12 +457,12 @@ $('#tree').treeview('disableAll', { silent: true }); Triggers `nodeDisabled` event; pass silent to suppress events. -#### disableNode(node | nodeId, options) +#### disableNode(nodes, options) -Disable a given tree node, accepts node or nodeId. +Disable given tree nodes. ```javascript -$('#tree').treeview('disableNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('disableNode', [ nodes, { silent: true } ]); ``` Triggers `nodeDisabled` event; pass silent to suppress events. @@ -477,12 +477,12 @@ $('#tree').treeview('enableAll', { silent: true }); Triggers `nodeEnabled` event; pass silent to suppress events. -#### enableNode(node | nodeId, options) +#### enableNode(nodes, options) -Enable a given tree node, accepts node or nodeId. +Enable given tree nodes. ```javascript -$('#tree').treeview('enableNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('enableNode', [ nodes, { silent: true } ]); ``` Triggers `nodeEnabled` event; pass silent to suppress events. @@ -497,12 +497,12 @@ $('#tree').treeview('expandAll', { levels: 2, silent: true }); Triggers `nodeExpanded` event; pass silent to suppress events. -#### expandNode(node | nodeId, options) +#### expandNode(nodes, options) -Expand a given tree node, accepts node or nodeId. Optionally can be expanded to any given number of levels. +Expand given tree nodes. Optionally can be expanded to any given number of levels. ```javascript -$('#tree').treeview('expandNode', [ nodeId, { levels: 2, silent: true } ]); +$('#tree').treeview('expandNode', [ nodes, { levels: 2, silent: true } ]); ``` Triggers `nodeExpanded` event; pass silent to suppress events. @@ -603,12 +603,12 @@ Removes the tree view component. Removing attached events, internal attached obj $('#tree').treeview('remove'); ``` -#### revealNode(node | nodeId, options) +#### revealNode(nodes, options) -Reveals a given tree node, expanding the tree from node to root. +Reveals given tree nodes, expanding the tree from node to root. ```javascript -$('#tree').treeview('revealNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('revealNode', [ nodes, { silent: true } ]); ``` Triggers `nodeExpanded` event; pass silent to suppress events. @@ -629,52 +629,52 @@ $('#tree').treeview('search', [ 'Parent', { Triggers `searchComplete` event -#### selectNode(node | nodeId, options) +#### selectNode(nodes, options) -Selects a given tree node, accepts node or nodeId. +Selects given tree nodes. ```javascript -$('#tree').treeview('selectNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('selectNode', [ nodes, { silent: true } ]); ``` Triggers `nodeSelected` event; pass silent to suppress events. -#### toggleNodeChecked(node | nodeId, options) +#### toggleNodeChecked(nodes, options) -Toggles a nodes checked state; checking if unchecked, unchecking if checked. +Toggles a node's checked state; checking if unchecked, unchecking if checked. ```javascript -$('#tree').treeview('toggleNodeChecked', [ nodeId, { silent: true } ]); +$('#tree').treeview('toggleNodeChecked', [ nodes, { silent: true } ]); ``` Triggers either `nodeChecked` or `nodeUnchecked` event; pass silent to suppress events. -#### toggleNodeDisabled(node | nodeId, options) +#### toggleNodeDisabled(nodes, options) -Toggles a nodes disabled state; disabling if enabled, enabling if disabled. +Toggles a node's disabled state; disabling if enabled, enabling if disabled. ```javascript -$('#tree').treeview('toggleNodeDisabled', [ nodeId, { silent: true } ]); +$('#tree').treeview('toggleNodeDisabled', [ nodes, { silent: true } ]); ``` Triggers either `nodeDisabled` or `nodeEnabled` event; pass silent to suppress events. -#### toggleNodeExpanded(node | nodeId, options) +#### toggleNodeExpanded(nodes, options) -Toggles a nodes expanded state; collapsing if expanded, expanding if collapsed. +Toggles a node's expanded state; collapsing if expanded, expanding if collapsed. ```javascript -$('#tree').treeview('toggleNodeExpanded', [ nodeId, { silent: true } ]); +$('#tree').treeview('toggleNodeExpanded', [ nodes, { silent: true } ]); ``` Triggers either `nodeExpanded` or `nodeCollapsed` event; pass silent to suppress events. -#### toggleNodeSelected(node | nodeId, options) +#### toggleNodeSelected(nodes, options) Toggles a node selected state; selecting if unselected, unselecting if selected. ```javascript -$('#tree').treeview('toggleNodeSelected', [ nodeId, { silent: true } ]); +$('#tree').treeview('toggleNodeSelected', [ nodes, { silent: true } ]); ``` Triggers either `nodeSelected` or `nodeUnselected` event; pass silent to suppress events. @@ -689,22 +689,22 @@ $('#tree').treeview('uncheckAll', { silent: true }); Triggers `nodeUnchecked` event; pass silent to suppress events. -#### uncheckNode(node | nodeId, options) +#### uncheckNode(nodes, options) -Uncheck a given tree node, accepts node or nodeId. +Uncheck given tree nodes. ```javascript -$('#tree').treeview('uncheckNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('uncheckNode', [ nodes, { silent: true } ]); ``` Triggers `nodeUnchecked` event; pass silent to suppress events. -#### unselectNode(node | nodeId, options) +#### unselectNode(nodes, options) -Unselects a given tree node, accepts node or nodeId. +Unselects given tree nodes. ```javascript -$('#tree').treeview('unselectNode', [ nodeId, { silent: true } ]); +$('#tree').treeview('unselectNode', [ nodes, { silent: true } ]); ``` Triggers `nodeUnselected` event; pass silent to suppress events. diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index f1ae9d05c..77cec00cf 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","g","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b));else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","g","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                      ',node:'
                                                                                                    • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,"g",b)},g.prototype.getParents=function(b){var c=[];return console.log("getParents nodes = ",b),a.each(b,a.proxy(function(a,b){console.log("getParents node = ",a,b),c.push(this._nodes[b.parentId])},this)),console.log("getParenst [] = ",c),c},g.prototype.getSiblings=function(b){console.log("getSiblings nodes = ",b);var c=[];return a.each(b,a.proxy(function(a,b){console.log("getSiblings node =",b);var d=this.getParents([b]);console.log("getSiblings parent = ",d);var e=d[0]?d[0].nodes:this._tree;console.log("getSiblings nodes 2 = ",e),e&&c.push(e.filter(function(a){return console.log("** match ",a.nodeId,b.nodeId),a.nodeId!==b.nodeId}))},this)),console.log("getSiblings siblingNodes = ",c),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!0,b)},this))},g.prototype.unselectNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setSelected(a,!1,b)},this))},g.prototype.toggleNodeSelected=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleSelected(a,b)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!1,b)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setExpanded(a,!0,b),a.nodes&&this._expandLevels(a.nodes,b.levels-1,b)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){for(var c,d=a;c=this.getParents([d])[0];)d=c,this._setExpanded(d,!0,b)},this))},g.prototype.toggleNodeExpanded=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleExpanded(a,b)},this))},g.prototype.checkAll=function(b){var c=this._findNodes("false","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.checkNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!0,b)},this))},g.prototype.uncheckAll=function(b){var c=this._findNodes("true","g","state.checked");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.uncheckNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setChecked(a,!1,b)},this))},g.prototype.toggleNodeChecked=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._toggleChecked(a,b)},this))},g.prototype.disableAll=function(b){var c=this._findNodes("false","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.disableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!0,b)},this))},g.prototype.enableAll=function(b){var c=this._findNodes("true","g","state.disabled");this._forEachIdentifier(c,b,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.enableNode=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!1,b)},this))},g.prototype.toggleNodeDisabled=function(b,c){this._forEachIdentifier(b,c,a.proxy(function(a,b){this._setDisabled(a,!a.state.disabled,b)},this))},g.prototype._forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this._identifyNode(b),c)},this))},g.prototype._identifyNode=function(a){return console.log("_identifyNode ",a),"number"==typeof a?this._nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","g","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"g",d=d||"text",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,d);return console.log("_findNode val = ",d,e),"string"==typeof e?e.match(new RegExp(b,c)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b));else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                        ',node:'
                                                                                                      • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index a26afa9e0..cdd783307 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -467,7 +467,7 @@ // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { - $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + $.each(this._findNodes('true', 'state.selected'), $.proxy(function (index, node) { this._setSelected(node, false, $.extend(options, {unselecting: true})); }, this)); } @@ -496,7 +496,7 @@ // If preventUnselect true + only one remaining selection, disable unselect if (this._options.preventUnselect && (options && !options.unselecting) && - (this._findNodes('true', 'g', 'state.selected').length === 1)) { + (this._findNodes('true', 'state.selected').length === 1)) { return this; } @@ -858,11 +858,11 @@ /** Returns an array of matching node objects. - @param {Number|String|Boolean|Undefined|Null} pattern - A pattern to match against a given field + @param {String} pattern - A pattern to match against a given field @return {String} field - Field to query pattern against */ Tree.prototype.findNodes = function (pattern, field) { - return this._findNodes(pattern, 'g', field); + return this._findNodes(pattern, field); }; /** @@ -872,12 +872,9 @@ */ Tree.prototype.getParents = function (nodes) { var parentNodes = []; - console.log('getParents nodes = ', nodes); $.each(nodes, $.proxy(function (index, node) { - console.log('getParents node = ', index, node); parentNodes.push(this._nodes[node.parentId]); }, this)); - console.log('getParenst [] = ', parentNodes); return parentNodes; }; @@ -887,23 +884,16 @@ @returns {Array} nodes - An array of sibling nodes */ Tree.prototype.getSiblings = function (nodes) { - console.log('getSiblings nodes = ', nodes); var siblingNodes = []; $.each(nodes, $.proxy(function (index, node) { - console.log('getSiblings node =', node); var parent = this.getParents([node]); - console.log('getSiblings parent = ', parent); var nodes = parent[0] ? parent[0].nodes : this._tree; - console.log('getSiblings nodes 2 = ', nodes); - if (nodes) { - siblingNodes.push(nodes.filter(function (obj) { - console.log('** match ', obj.nodeId, node.nodeId); - return obj.nodeId !== node.nodeId; - }) - ); - } + siblingNodes = nodes.filter(function (obj) { + return obj.nodeId !== node.nodeId; + }); }, this)); - console.log('getSiblings siblingNodes = ', siblingNodes); + + // flatten possible nested array before returning return $.map(siblingNodes, function (obj) { return obj; }); @@ -914,7 +904,7 @@ @returns {Array} nodes - Selected nodes */ Tree.prototype.getSelected = function () { - return this._findNodes('true', 'g', 'state.selected'); + return this._findNodes('true', 'state.selected'); }; /** @@ -922,7 +912,7 @@ @returns {Array} nodes - Unselected nodes */ Tree.prototype.getUnselected = function () { - return this._findNodes('false', 'g', 'state.selected'); + return this._findNodes('false', 'state.selected'); }; /** @@ -930,7 +920,7 @@ @returns {Array} nodes - Expanded nodes */ Tree.prototype.getExpanded = function () { - return this._findNodes('true', 'g', 'state.expanded'); + return this._findNodes('true', 'state.expanded'); }; /** @@ -938,7 +928,7 @@ @returns {Array} nodes - Collapsed nodes */ Tree.prototype.getCollapsed = function () { - return this._findNodes('false', 'g', 'state.expanded'); + return this._findNodes('false', 'state.expanded'); }; /** @@ -946,7 +936,7 @@ @returns {Array} nodes - Checked nodes */ Tree.prototype.getChecked = function () { - return this._findNodes('true', 'g', 'state.checked'); + return this._findNodes('true', 'state.checked'); }; /** @@ -954,7 +944,7 @@ @returns {Array} nodes - Unchecked nodes */ Tree.prototype.getUnchecked = function () { - return this._findNodes('false', 'g', 'state.checked'); + return this._findNodes('false', 'state.checked'); }; /** @@ -962,7 +952,7 @@ @returns {Array} nodes - Disabled nodes */ Tree.prototype.getDisabled = function () { - return this._findNodes('true', 'g', 'state.disabled'); + return this._findNodes('true', 'state.disabled'); }; /** @@ -970,39 +960,42 @@ @returns {Array} nodes - Enabled nodes */ Tree.prototype.getEnabled = function () { - return this._findNodes('false', 'g', 'state.disabled'); + return this._findNodes('false', 'state.disabled'); }; /** - Set a node state to selected - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Selects given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.selectNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.selectNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, true, options); }, this)); }; /** - Set a node state to unselected - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Unselects given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.unselectNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.unselectNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, false, options); }, this)); }; /** Toggles a node selected state; selecting if unselected, unselecting if selected. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeSelected = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeSelected = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleSelected(node, options); }, this)); }; @@ -1020,11 +1013,12 @@ /** Collapse a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.collapseNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.collapseNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, false, options); }, this)); }; @@ -1040,12 +1034,13 @@ }; /** - Expand a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Expand given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.expandNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.expandNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); @@ -1063,12 +1058,13 @@ }; /** - Reveals a given tree node, expanding the tree from node to root. - @param {Object|Number|Array} identifiers - A valid node, node id or array of node identifiers + Reveals given tree nodes, expanding the tree from node to root. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.revealNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.revealNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { var parentNode = node; var tmpNode; while (tmpNode = this.getParents([parentNode])[0]) { @@ -1079,12 +1075,13 @@ }; /** - Toggles a nodes expanded state; collapsing if expanded, expanding if collapsed. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's expanded state; collapsing if expanded, expanding if collapsed. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeExpanded = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeExpanded = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleExpanded(node, options); }, this)); }; @@ -1095,19 +1092,21 @@ @param {optional Object} options */ Tree.prototype.checkAll = function (options) { - var identifiers = this._findNodes('false', 'g', 'state.checked'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.checked'); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); }; /** - Check a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Checks given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.checkNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.checkNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); }; @@ -1117,30 +1116,33 @@ @param {optional Object} options */ Tree.prototype.uncheckAll = function (options) { - var identifiers = this._findNodes('true', 'g', 'state.checked'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.checked'); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); }; /** - Uncheck a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Uncheck given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.uncheckNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.uncheckNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); }; /** - Toggles a nodes checked state; checking if unchecked, unchecking if checked. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's checked state; checking if unchecked, unchecking if checked. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeChecked = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeChecked = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleChecked(node, options); }, this)); }; @@ -1151,19 +1153,21 @@ @param {optional Object} options */ Tree.prototype.disableAll = function (options) { - var identifiers = this._findNodes('false', 'g', 'state.disabled'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.disabled'); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); }; /** - Disable a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Disable given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.disableNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.disableNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); }; @@ -1173,60 +1177,37 @@ @param {optional Object} options */ Tree.prototype.enableAll = function (options) { - var identifiers = this._findNodes('true', 'g', 'state.disabled'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.disabled'); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); }; /** - Enable a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Enable given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.enableNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.enableNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); }; /** - Toggles a nodes disabled state; disabling is enabled, enabling if disabled. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's disabled state; disabling is enabled, enabling if disabled. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeDisabled = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabled(node, !node.state.disabled, options); - }, this)); - }; - - - /** - Common code for processing multiple identifiers - */ - Tree.prototype._forEachIdentifier = function (identifiers, options, callback) { - + Tree.prototype.toggleNodeDisabled = function (nodes, options) { options = $.extend({}, _default.options, options); - - if (!(identifiers instanceof Array)) { - identifiers = [identifiers]; - } - - $.each(identifiers, $.proxy(function (index, identifier) { - callback(this._identifyNode(identifier), options); + $.each(nodes, $.proxy(function (index, node) { + this._setDisabled(node, !node.state.disabled, options); }, this)); }; - /* - Identifies a node from either a node id or object - */ - Tree.prototype._identifyNode = function (identifier) { - console.log('_identifyNode ', identifier); - return ((typeof identifier) === 'number') ? - this._nodes[identifier] : - identifier; - }; /** Searches the tree for nodes (text) that match given criteria @@ -1251,7 +1232,7 @@ modifier += 'i'; } - results = this._findNodes(pattern, modifier); + results = this._findNodes(pattern, 'text', modifier); } // Clear previous results no longer matched @@ -1278,7 +1259,6 @@ Clears previous search results */ Tree.prototype.clearSearch = function (options) { - options = $.extend({}, { render: true }, options); var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { @@ -1289,7 +1269,7 @@ }; Tree.prototype._getSearchResults = function () { - return this._findNodes('true', 'g', 'searchResult'); + return this._findNodes('true', 'searchResult'); }; Tree.prototype._diffArray = function (a, b) { @@ -1305,18 +1285,17 @@ /** Find nodes that match a given criteria @param {String} pattern - A given string to match against - @param {optional String} modifier - Valid RegEx modifiers @param {optional String} attribute - Attribute to compare pattern against + @param {optional String} modifier - Valid RegEx modifiers @return {Array} nodes - Nodes that match your criteria */ - Tree.prototype._findNodes = function (pattern, modifier, attribute) { + Tree.prototype._findNodes = function (pattern, attribute, modifier) { - modifier = modifier || 'g'; attribute = attribute || 'text'; + modifier = modifier || 'g'; return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); - console.log('_findNode val = ', attribute, val); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index fa6f5aaed..cdd783307 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -467,7 +467,7 @@ // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { - $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + $.each(this._findNodes('true', 'state.selected'), $.proxy(function (index, node) { this._setSelected(node, false, $.extend(options, {unselecting: true})); }, this)); } @@ -496,7 +496,7 @@ // If preventUnselect true + only one remaining selection, disable unselect if (this._options.preventUnselect && (options && !options.unselecting) && - (this._findNodes('true', 'g', 'state.selected').length === 1)) { + (this._findNodes('true', 'state.selected').length === 1)) { return this; } @@ -858,11 +858,11 @@ /** Returns an array of matching node objects. - @param {Number|String|Boolean|Undefined|Null} pattern - A pattern to match against a given field + @param {String} pattern - A pattern to match against a given field @return {String} field - Field to query pattern against */ Tree.prototype.findNodes = function (pattern, field) { - return this._findNodes(pattern, 'g', field); + return this._findNodes(pattern, field); }; /** @@ -884,17 +884,19 @@ @returns {Array} nodes - An array of sibling nodes */ Tree.prototype.getSiblings = function (nodes) { - return $.map( - $.each(nodes, $.proxy(function (index, node) { - var parent = this.getParents([node]); - var nodes = parent[0] ? parent[0].nodes : this._tree; - return nodes.filter(function (obj) { - return obj.nodeId !== node.nodeId; - }); - }, this), function (obj) { - return obj; - } - ); + var siblingNodes = []; + $.each(nodes, $.proxy(function (index, node) { + var parent = this.getParents([node]); + var nodes = parent[0] ? parent[0].nodes : this._tree; + siblingNodes = nodes.filter(function (obj) { + return obj.nodeId !== node.nodeId; + }); + }, this)); + + // flatten possible nested array before returning + return $.map(siblingNodes, function (obj) { + return obj; + }); }; /** @@ -902,7 +904,7 @@ @returns {Array} nodes - Selected nodes */ Tree.prototype.getSelected = function () { - return this._findNodes('true', 'g', 'state.selected'); + return this._findNodes('true', 'state.selected'); }; /** @@ -910,7 +912,7 @@ @returns {Array} nodes - Unselected nodes */ Tree.prototype.getUnselected = function () { - return this._findNodes('false', 'g', 'state.selected'); + return this._findNodes('false', 'state.selected'); }; /** @@ -918,7 +920,7 @@ @returns {Array} nodes - Expanded nodes */ Tree.prototype.getExpanded = function () { - return this._findNodes('true', 'g', 'state.expanded'); + return this._findNodes('true', 'state.expanded'); }; /** @@ -926,7 +928,7 @@ @returns {Array} nodes - Collapsed nodes */ Tree.prototype.getCollapsed = function () { - return this._findNodes('false', 'g', 'state.expanded'); + return this._findNodes('false', 'state.expanded'); }; /** @@ -934,7 +936,7 @@ @returns {Array} nodes - Checked nodes */ Tree.prototype.getChecked = function () { - return this._findNodes('true', 'g', 'state.checked'); + return this._findNodes('true', 'state.checked'); }; /** @@ -942,7 +944,7 @@ @returns {Array} nodes - Unchecked nodes */ Tree.prototype.getUnchecked = function () { - return this._findNodes('false', 'g', 'state.checked'); + return this._findNodes('false', 'state.checked'); }; /** @@ -950,7 +952,7 @@ @returns {Array} nodes - Disabled nodes */ Tree.prototype.getDisabled = function () { - return this._findNodes('true', 'g', 'state.disabled'); + return this._findNodes('true', 'state.disabled'); }; /** @@ -958,39 +960,42 @@ @returns {Array} nodes - Enabled nodes */ Tree.prototype.getEnabled = function () { - return this._findNodes('false', 'g', 'state.disabled'); + return this._findNodes('false', 'state.disabled'); }; /** - Set a node state to selected - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Selects given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.selectNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.selectNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, true, options); }, this)); }; /** - Set a node state to unselected - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Unselects given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.unselectNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.unselectNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, false, options); }, this)); }; /** Toggles a node selected state; selecting if unselected, unselecting if selected. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeSelected = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeSelected = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleSelected(node, options); }, this)); }; @@ -1008,11 +1013,12 @@ /** Collapse a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.collapseNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.collapseNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, false, options); }, this)); }; @@ -1028,12 +1034,13 @@ }; /** - Expand a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Expand given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.expandNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.expandNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); @@ -1051,12 +1058,13 @@ }; /** - Reveals a given tree node, expanding the tree from node to root. - @param {Object|Number|Array} identifiers - A valid node, node id or array of node identifiers + Reveals given tree nodes, expanding the tree from node to root. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.revealNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.revealNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { var parentNode = node; var tmpNode; while (tmpNode = this.getParents([parentNode])[0]) { @@ -1067,12 +1075,13 @@ }; /** - Toggles a nodes expanded state; collapsing if expanded, expanding if collapsed. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's expanded state; collapsing if expanded, expanding if collapsed. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeExpanded = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeExpanded = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleExpanded(node, options); }, this)); }; @@ -1083,19 +1092,21 @@ @param {optional Object} options */ Tree.prototype.checkAll = function (options) { - var identifiers = this._findNodes('false', 'g', 'state.checked'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.checked'); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); }; /** - Check a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Checks given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.checkNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.checkNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); }; @@ -1105,30 +1116,33 @@ @param {optional Object} options */ Tree.prototype.uncheckAll = function (options) { - var identifiers = this._findNodes('true', 'g', 'state.checked'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.checked'); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); }; /** - Uncheck a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Uncheck given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.uncheckNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.uncheckNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); }; /** - Toggles a nodes checked state; checking if unchecked, unchecking if checked. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's checked state; checking if unchecked, unchecking if checked. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeChecked = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeChecked = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleChecked(node, options); }, this)); }; @@ -1139,19 +1153,21 @@ @param {optional Object} options */ Tree.prototype.disableAll = function (options) { - var identifiers = this._findNodes('false', 'g', 'state.disabled'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.disabled'); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); }; /** - Disable a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Disable given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.disableNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.disableNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); }; @@ -1161,59 +1177,37 @@ @param {optional Object} options */ Tree.prototype.enableAll = function (options) { - var identifiers = this._findNodes('true', 'g', 'state.disabled'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.disabled'); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); }; /** - Enable a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Enable given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.enableNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.enableNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); }; /** - Toggles a nodes disabled state; disabling is enabled, enabling if disabled. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's disabled state; disabling is enabled, enabling if disabled. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeDisabled = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabled(node, !node.state.disabled, options); - }, this)); - }; - - - /** - Common code for processing multiple identifiers - */ - Tree.prototype._forEachIdentifier = function (identifiers, options, callback) { - + Tree.prototype.toggleNodeDisabled = function (nodes, options) { options = $.extend({}, _default.options, options); - - if (!(identifiers instanceof Array)) { - identifiers = [identifiers]; - } - - $.each(identifiers, $.proxy(function (index, identifier) { - callback(this._identifyNode(identifier), options); + $.each(nodes, $.proxy(function (index, node) { + this._setDisabled(node, !node.state.disabled, options); }, this)); }; - /* - Identifies a node from either a node id or object - */ - Tree.prototype._identifyNode = function (identifier) { - return ((typeof identifier) === 'number') ? - this._nodes[identifier] : - identifier; - }; /** Searches the tree for nodes (text) that match given criteria @@ -1238,7 +1232,7 @@ modifier += 'i'; } - results = this._findNodes(pattern, modifier); + results = this._findNodes(pattern, 'text', modifier); } // Clear previous results no longer matched @@ -1265,7 +1259,6 @@ Clears previous search results */ Tree.prototype.clearSearch = function (options) { - options = $.extend({}, { render: true }, options); var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { @@ -1276,7 +1269,7 @@ }; Tree.prototype._getSearchResults = function () { - return this._findNodes('true', 'g', 'searchResult'); + return this._findNodes('true', 'searchResult'); }; Tree.prototype._diffArray = function (a, b) { @@ -1292,14 +1285,14 @@ /** Find nodes that match a given criteria @param {String} pattern - A given string to match against - @param {optional String} modifier - Valid RegEx modifiers @param {optional String} attribute - Attribute to compare pattern against + @param {optional String} modifier - Valid RegEx modifiers @return {Array} nodes - Nodes that match your criteria */ - Tree.prototype._findNodes = function (pattern, modifier, attribute) { + Tree.prototype._findNodes = function (pattern, attribute, modifier) { - modifier = modifier || 'g'; attribute = attribute || 'text'; + modifier = modifier || 'g'; return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index a26afa9e0..cdd783307 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -467,7 +467,7 @@ // If multiSelect false, unselect previously selected if (!this._options.multiSelect) { - $.each(this._findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + $.each(this._findNodes('true', 'state.selected'), $.proxy(function (index, node) { this._setSelected(node, false, $.extend(options, {unselecting: true})); }, this)); } @@ -496,7 +496,7 @@ // If preventUnselect true + only one remaining selection, disable unselect if (this._options.preventUnselect && (options && !options.unselecting) && - (this._findNodes('true', 'g', 'state.selected').length === 1)) { + (this._findNodes('true', 'state.selected').length === 1)) { return this; } @@ -858,11 +858,11 @@ /** Returns an array of matching node objects. - @param {Number|String|Boolean|Undefined|Null} pattern - A pattern to match against a given field + @param {String} pattern - A pattern to match against a given field @return {String} field - Field to query pattern against */ Tree.prototype.findNodes = function (pattern, field) { - return this._findNodes(pattern, 'g', field); + return this._findNodes(pattern, field); }; /** @@ -872,12 +872,9 @@ */ Tree.prototype.getParents = function (nodes) { var parentNodes = []; - console.log('getParents nodes = ', nodes); $.each(nodes, $.proxy(function (index, node) { - console.log('getParents node = ', index, node); parentNodes.push(this._nodes[node.parentId]); }, this)); - console.log('getParenst [] = ', parentNodes); return parentNodes; }; @@ -887,23 +884,16 @@ @returns {Array} nodes - An array of sibling nodes */ Tree.prototype.getSiblings = function (nodes) { - console.log('getSiblings nodes = ', nodes); var siblingNodes = []; $.each(nodes, $.proxy(function (index, node) { - console.log('getSiblings node =', node); var parent = this.getParents([node]); - console.log('getSiblings parent = ', parent); var nodes = parent[0] ? parent[0].nodes : this._tree; - console.log('getSiblings nodes 2 = ', nodes); - if (nodes) { - siblingNodes.push(nodes.filter(function (obj) { - console.log('** match ', obj.nodeId, node.nodeId); - return obj.nodeId !== node.nodeId; - }) - ); - } + siblingNodes = nodes.filter(function (obj) { + return obj.nodeId !== node.nodeId; + }); }, this)); - console.log('getSiblings siblingNodes = ', siblingNodes); + + // flatten possible nested array before returning return $.map(siblingNodes, function (obj) { return obj; }); @@ -914,7 +904,7 @@ @returns {Array} nodes - Selected nodes */ Tree.prototype.getSelected = function () { - return this._findNodes('true', 'g', 'state.selected'); + return this._findNodes('true', 'state.selected'); }; /** @@ -922,7 +912,7 @@ @returns {Array} nodes - Unselected nodes */ Tree.prototype.getUnselected = function () { - return this._findNodes('false', 'g', 'state.selected'); + return this._findNodes('false', 'state.selected'); }; /** @@ -930,7 +920,7 @@ @returns {Array} nodes - Expanded nodes */ Tree.prototype.getExpanded = function () { - return this._findNodes('true', 'g', 'state.expanded'); + return this._findNodes('true', 'state.expanded'); }; /** @@ -938,7 +928,7 @@ @returns {Array} nodes - Collapsed nodes */ Tree.prototype.getCollapsed = function () { - return this._findNodes('false', 'g', 'state.expanded'); + return this._findNodes('false', 'state.expanded'); }; /** @@ -946,7 +936,7 @@ @returns {Array} nodes - Checked nodes */ Tree.prototype.getChecked = function () { - return this._findNodes('true', 'g', 'state.checked'); + return this._findNodes('true', 'state.checked'); }; /** @@ -954,7 +944,7 @@ @returns {Array} nodes - Unchecked nodes */ Tree.prototype.getUnchecked = function () { - return this._findNodes('false', 'g', 'state.checked'); + return this._findNodes('false', 'state.checked'); }; /** @@ -962,7 +952,7 @@ @returns {Array} nodes - Disabled nodes */ Tree.prototype.getDisabled = function () { - return this._findNodes('true', 'g', 'state.disabled'); + return this._findNodes('true', 'state.disabled'); }; /** @@ -970,39 +960,42 @@ @returns {Array} nodes - Enabled nodes */ Tree.prototype.getEnabled = function () { - return this._findNodes('false', 'g', 'state.disabled'); + return this._findNodes('false', 'state.disabled'); }; /** - Set a node state to selected - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Selects given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.selectNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.selectNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, true, options); }, this)); }; /** - Set a node state to unselected - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Unselects given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.unselectNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.unselectNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, false, options); }, this)); }; /** Toggles a node selected state; selecting if unselected, unselecting if selected. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeSelected = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeSelected = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleSelected(node, options); }, this)); }; @@ -1020,11 +1013,12 @@ /** Collapse a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.collapseNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.collapseNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, false, options); }, this)); }; @@ -1040,12 +1034,13 @@ }; /** - Expand a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Expand given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.expandNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.expandNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, true, options); if (node.nodes) { this._expandLevels(node.nodes, options.levels-1, options); @@ -1063,12 +1058,13 @@ }; /** - Reveals a given tree node, expanding the tree from node to root. - @param {Object|Number|Array} identifiers - A valid node, node id or array of node identifiers + Reveals given tree nodes, expanding the tree from node to root. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.revealNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.revealNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { var parentNode = node; var tmpNode; while (tmpNode = this.getParents([parentNode])[0]) { @@ -1079,12 +1075,13 @@ }; /** - Toggles a nodes expanded state; collapsing if expanded, expanding if collapsed. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's expanded state; collapsing if expanded, expanding if collapsed. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeExpanded = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeExpanded = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleExpanded(node, options); }, this)); }; @@ -1095,19 +1092,21 @@ @param {optional Object} options */ Tree.prototype.checkAll = function (options) { - var identifiers = this._findNodes('false', 'g', 'state.checked'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.checked'); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); }; /** - Check a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Checks given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.checkNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.checkNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); }; @@ -1117,30 +1116,33 @@ @param {optional Object} options */ Tree.prototype.uncheckAll = function (options) { - var identifiers = this._findNodes('true', 'g', 'state.checked'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.checked'); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); }; /** - Uncheck a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Uncheck given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.uncheckNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.uncheckNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); }; /** - Toggles a nodes checked state; checking if unchecked, unchecking if checked. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's checked state; checking if unchecked, unchecking if checked. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeChecked = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.toggleNodeChecked = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleChecked(node, options); }, this)); }; @@ -1151,19 +1153,21 @@ @param {optional Object} options */ Tree.prototype.disableAll = function (options) { - var identifiers = this._findNodes('false', 'g', 'state.disabled'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.disabled'); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); }; /** - Disable a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Disable given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.disableNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.disableNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); }; @@ -1173,60 +1177,37 @@ @param {optional Object} options */ Tree.prototype.enableAll = function (options) { - var identifiers = this._findNodes('true', 'g', 'state.disabled'); - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.disabled'); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); }; /** - Enable a given tree node - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Enable given tree nodes + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.enableNode = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + Tree.prototype.enableNode = function (nodes, options) { + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); }; /** - Toggles a nodes disabled state; disabling is enabled, enabling if disabled. - @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + Toggles a node's disabled state; disabling is enabled, enabling if disabled. + @param {Array} nodes - An array of nodes @param {optional Object} options */ - Tree.prototype.toggleNodeDisabled = function (identifiers, options) { - this._forEachIdentifier(identifiers, options, $.proxy(function (node, options) { - this._setDisabled(node, !node.state.disabled, options); - }, this)); - }; - - - /** - Common code for processing multiple identifiers - */ - Tree.prototype._forEachIdentifier = function (identifiers, options, callback) { - + Tree.prototype.toggleNodeDisabled = function (nodes, options) { options = $.extend({}, _default.options, options); - - if (!(identifiers instanceof Array)) { - identifiers = [identifiers]; - } - - $.each(identifiers, $.proxy(function (index, identifier) { - callback(this._identifyNode(identifier), options); + $.each(nodes, $.proxy(function (index, node) { + this._setDisabled(node, !node.state.disabled, options); }, this)); }; - /* - Identifies a node from either a node id or object - */ - Tree.prototype._identifyNode = function (identifier) { - console.log('_identifyNode ', identifier); - return ((typeof identifier) === 'number') ? - this._nodes[identifier] : - identifier; - }; /** Searches the tree for nodes (text) that match given criteria @@ -1251,7 +1232,7 @@ modifier += 'i'; } - results = this._findNodes(pattern, modifier); + results = this._findNodes(pattern, 'text', modifier); } // Clear previous results no longer matched @@ -1278,7 +1259,6 @@ Clears previous search results */ Tree.prototype.clearSearch = function (options) { - options = $.extend({}, { render: true }, options); var results = $.each(this._getSearchResults(), $.proxy(function (index, node) { @@ -1289,7 +1269,7 @@ }; Tree.prototype._getSearchResults = function () { - return this._findNodes('true', 'g', 'searchResult'); + return this._findNodes('true', 'searchResult'); }; Tree.prototype._diffArray = function (a, b) { @@ -1305,18 +1285,17 @@ /** Find nodes that match a given criteria @param {String} pattern - A given string to match against - @param {optional String} modifier - Valid RegEx modifiers @param {optional String} attribute - Attribute to compare pattern against + @param {optional String} modifier - Valid RegEx modifiers @return {Array} nodes - Nodes that match your criteria */ - Tree.prototype._findNodes = function (pattern, modifier, attribute) { + Tree.prototype._findNodes = function (pattern, attribute, modifier) { - modifier = modifier || 'g'; attribute = attribute || 'text'; + modifier = modifier || 'g'; return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); - console.log('_findNode val = ', attribute, val); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); } diff --git a/tests/tests.js b/tests/tests.js index 72d946462..62bb8ad24 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -547,20 +547,20 @@ }); test('getSelected', function () { - var $tree = init({ data: data }) - .treeview('selectNode', 0); + var tree = init({ data: data }).treeview(true); + tree.selectNode(tree.findNodes('Parent 1', 'text')); - var selectedNodes = $tree.treeview('getSelected'); + var selectedNodes = tree.getSelected(); ok((selectedNodes instanceof Array), 'Result is an array'); equal(selectedNodes.length, 1, 'Correct number of nodes returned'); equal(selectedNodes[0].text, 'Parent 1', 'Correct node returned'); }); test('getUnselected', function () { - var $tree = init({ data: data }) - .treeview('selectNode', 0); + var tree = init({ data: data }).treeview(true); + tree.selectNode(tree.findNodes('Parent 1', 'text')); - var unselectedNodes = $tree.treeview('getUnselected'); + var unselectedNodes = tree.getUnselected(); ok((unselectedNodes instanceof Array), 'Result is an array'); equal(unselectedNodes.length, 8, 'Correct number of nodes returned'); }); @@ -569,8 +569,8 @@ // Default tree + expanded to 2 levels, // means 1 node 'Parent 1' should be expanded and therefore returned test('getExpanded', function () { - var $tree = init({ data: data }); - var expandedNodes = $tree.treeview('getExpanded'); + var tree = init({ data: data }).treeview(true); + var expandedNodes = tree.getExpanded(); ok((expandedNodes instanceof Array), 'Result is an array'); equal(expandedNodes.length, 1, 'Correct number of nodes returned'); equal(expandedNodes[0].text, 'Parent 1', 'Correct node returned'); @@ -581,46 +581,46 @@ // as all other parent nodes have no children their state will be collapsed // which means 8 of the 9 nodes should be returned test('getCollapsed', function () { - var $tree = init({ data: data }); - var collapsedNodes = $tree.treeview('getCollapsed'); + var tree = init({ data: data }).treeview(true); + var collapsedNodes = tree.getCollapsed(); ok((collapsedNodes instanceof Array), 'Result is an array'); equal(collapsedNodes.length, 8, 'Correct number of nodes returned'); }); test('getChecked', function () { - var $tree = init({ data: data, showCheckbox: true }) - .treeview('checkNode', 0); + var tree = init({ data: data }).treeview(true); + tree.checkNode(tree.findNodes('Parent 1', 'text')); - var checkedNodes = $tree.treeview('getChecked'); + var checkedNodes = tree.getChecked(); ok((checkedNodes instanceof Array), 'Result is an array'); equal(checkedNodes.length, 1, 'Correct number of nodes returned'); equal(checkedNodes[0].text, 'Parent 1', 'Correct node returned'); }); test('getUnchecked', function () { - var $tree = init({ data: data }) - .treeview('checkNode', 0); + var tree = init({ data: data }).treeview(true); + tree.checkNode(tree.findNodes('Parent 1', 'text')); - var uncheckedNodes = $tree.treeview('getUnchecked'); + var uncheckedNodes = tree.getUnchecked(); ok((uncheckedNodes instanceof Array), 'Result is an array'); equal(uncheckedNodes.length, 8, 'Correct number of nodes returned'); }); test('getDisabled', function () { - var $tree = init({ data: data }) - .treeview('disableNode', 0); + var tree = init({ data: data }).treeview(true); + tree.disableNode(tree.findNodes('Parent 1', 'text')); - var disabledNodes = $tree.treeview('getDisabled'); + var disabledNodes = tree.getDisabled(); ok((disabledNodes instanceof Array), 'Result is an array'); equal(disabledNodes.length, 1, 'Correct number of nodes returned'); equal(disabledNodes[0].text, 'Parent 1', 'Correct node returned'); }); test('getEnabled', function () { - var $tree = init({ data: data }) - .treeview('disableNode', 0); + var tree = init({ data: data }).treeview(true); + tree.disableNode(tree.findNodes('Parent 1', 'text')); - var enabledNodes = $tree.treeview('getEnabled'); + var enabledNodes = tree.getEnabled(); ok((enabledNodes instanceof Array), 'Result is an array'); equal(enabledNodes.length, 8, 'Correct number of nodes returned'); }); @@ -776,9 +776,6 @@ tree.revealNode(tree.findNodes('Child 1', 'text')); equal($($tree.selector + ' ul li:not(.node-hidden)').length, 7, 'Reveal node works, reveal Child 1 and 7 nodes displayed'); - - $tree.treeview('revealNode', tree.findNodes('Grandchild 1', 'text')); - equal($($tree.selector + ' ul li:not(.node-hidden)').length, 9, 'Reveal node (by node) works, reveal Grandchild 1 and 9 nodes displayed'); }); test('search', function () { From a55100ad04ad1783f410281fc45ebf67b8963ae6 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Wed, 1 Jun 2016 21:24:31 +0100 Subject: [PATCH 30/52] Update README with proposed changes --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 0e34b680b..b11132223 100644 --- a/README.md +++ b/README.md @@ -737,6 +737,18 @@ $('#tree').on('nodeSelected', function(event, data) { ### List of Events +#### Lifecycle Events + +`initialized (event, nodes)` - The tree has initialized itself and data ready for rendering. + +`nodeRendered (event, node)` - A new node is rendered; + +`rendered (event, nodes)` - The tree is rendered; + +`destroyed (event)` The tree is being destroyed; + +#### State Events + `nodeChecked (event, node)` - A node is checked. `nodeCollapsed (event, node)` - A node is collapsed. @@ -753,6 +765,8 @@ $('#tree').on('nodeSelected', function(event, data) { `nodeUnselected (event, node)` - A node is unselected. +#### Other Events + `searchComplete (event, results)` - After a search completes `searchCleared (event, results)` - After search results are cleared From b54431c8ac3751f13c26eb2d6649d91bdeb808c9 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Thu, 2 Jun 2016 19:34:07 +0100 Subject: [PATCH 31/52] Implement basic lifecycle events - initialised, nodeRendered, rendered, destroyed --- README.md | 3 + dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 119 ++++++++++++++++++++------------ src/js/bootstrap-treeview.js | 113 ++++++++++++++++++------------ tests/lib/bootstrap-treeview.js | 119 ++++++++++++++++++++------------ tests/tests.js | 36 ++++++++++ 6 files changed, 259 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index b11132223..46c301647 100644 --- a/README.md +++ b/README.md @@ -735,10 +735,13 @@ $('#tree').on('nodeSelected', function(event, data) { }); ``` + ### List of Events #### Lifecycle Events +> Use callback handlers for lifecycle events otherwise you'll miss the events fired during creation. + `initialized (event, nodes)` - The tree has initialized itself and data ready for rendering. `nodeRendered (event, node)` - A new node is rendered; diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 77cec00cf..23ff8c014 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._setInitialStates({nodes:this._tree},0),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this.$wrapper.remove(),this.$wrapper=null,this._unsubscribeEvents(),this._initialized=!1)},g.prototype._unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e._nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),c>e._options.levels?b.state.visible=!1:b.state.visible=!0,b.state.hasOwnProperty("selected")||(b.state.selected=!1),e._nodes.push(b),b.nodes&&(b.nodes.length>0?e._setInitialStates(b,c):delete b.nodes)})}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),d&&!d.silent&&this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),d&&!d.silent&&this.$element.trigger("nodeCollapsed",a.extend(!0,{},b))))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),d&&!d.silent&&this.$element.trigger("nodeSelected",a.extend(!0,{},b));else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),d&&!d.silent&&this.$element.trigger("nodeUnselected",a.extend(!0,{},b))}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(b,c,d){d&&c===b.state.checked||(c?(b.state.checked=!0,b.$el&&(b.$el.addClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),d&&!d.silent&&this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,b.$el&&(b.$el.removeClass("node-checked"),b.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),d&&!d.silent&&this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype._setDisabled=function(b,c,d){d&&c===b.state.disabled||(c?(b.state.disabled=!0,this._setSelected(b,!1,d),this._setChecked(b,!1,d),this._setExpanded(b,!1,d),b.$el&&b.$el.addClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,b.$el&&b.$el.removeClass("node-disabled"),d&&!d.silent&&this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                          ',node:'
                                                                                                        • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this.$element.trigger("searchComplete",a.extend(!0,{},e)),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),a.when.apply(this,this._setInitialStates({nodes:this._tree},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes)},this)),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){(!d||d&&!d.silent)&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                            ',node:'
                                                                                                          • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index cdd783307..52d532076 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -60,6 +60,17 @@ preventUnselect: false, // Event handlers + onInitialized: undefined, + onNodeRendered: undefined, + onRendered: undefined, + onDestroyed: undefined, + + // onNodeHover: undefined, + // onNodeClicked: undefined, + // onNodeDblClicked: undefined, + // onNodeContextMenuClicked: undefined, + // onNodeTagClicked: undefined, + onNodeChecked: undefined, onNodeCollapsed: undefined, onNodeDisabled: undefined, @@ -68,6 +79,7 @@ onNodeSelected: undefined, onNodeUnchecked: undefined, onNodeUnselected: undefined, + onSearchComplete: undefined, onSearchCleared: undefined }; @@ -84,7 +96,6 @@ }; var Tree = function (element, options) { - this.$element = $(element); this._elementId = element.id; this._styleId = this._elementId + '-style'; @@ -147,7 +158,6 @@ }; Tree.prototype._init = function (options) { - this._tree = []; this._nodes = []; this._initialized = false; @@ -163,7 +173,14 @@ this._destroy(); this._subscribeEvents(); - this._setInitialStates({ nodes: this._tree }, 0); + + // index nodes + $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) + .done($.proxy(function () { + this._triggerEvent('initialized', this._nodes); + }, this)); + + // render to DOM this._render(); }; @@ -174,21 +191,24 @@ }; Tree.prototype._destroy = function () { - if (!this._initialized) return; + this._initialized = false; - this.$wrapper.remove(); - this.$wrapper = null; + this._triggerEvent('destroyed', null); // Switch off events this._unsubscribeEvents(); - // Reset this._initialized flag - this._initialized = false; + // Tear down + this.$wrapper.remove(); + this.$wrapper = null; }; Tree.prototype._unsubscribeEvents = function () { - + this.$element.off('initialized'); + this.$element.off('nodeRendered'); + this.$element.off('rendered'); + this.$element.off('destroyed'); this.$element.off('click'); this.$element.off('nodeChecked'); this.$element.off('nodeCollapsed'); @@ -203,9 +223,24 @@ }; Tree.prototype._subscribeEvents = function () { - this._unsubscribeEvents(); + if (typeof (this._options.onInitialized) === 'function') { + this.$element.on('initialized', this._options.onInitialized); + } + + if (typeof (this._options.onNodeRendered) === 'function') { + this.$element.on('nodeRendered', this._options.onNodeRendered); + } + + if (typeof (this._options.onRendered) === 'function') { + this.$element.on('rendered', this._options.onRendered); + } + + if (typeof (this._options.onDestroyed) === 'function') { + this.$element.on('destroyed', this._options.onDestroyed); + } + this.$element.on('click', $.proxy(this._clickHandler, this)); if (typeof (this._options.onNodeChecked) === 'function') { @@ -249,20 +284,29 @@ } }; + Tree.prototype._triggerEvent = function (event, data, options) { + if (!options || (options && !options.silent)) { + this.$element.trigger(event, $.extend(true, {}, data)); + } + } + /* Recurse the tree structure and ensure all nodes have valid initial states. User defined states will be preserved. For performance we also take this opportunity to index nodes in a flattened structure */ - Tree.prototype._setInitialStates = function (node, level) { + Tree.prototype._setInitialStates = function (node, level, ready) { if (!node.nodes) return; level += 1; + ready = ready || []; var parent = node; var _this = this; $.each(node.nodes, function checkStates(index, node) { + var deferred = new $.Deferred(); + ready.push(deferred.promise()); // nodeId : unique, incremental identifier node.nodeId = _this._nodes.length; @@ -319,13 +363,17 @@ // recurse child nodes and transverse the tree if (node.nodes) { if (node.nodes.length > 0) { - _this._setInitialStates(node, level); + _this._setInitialStates(node, level, ready); } else { delete node.nodes; } } + + deferred.resolve(); }); + + return ready; }; Tree.prototype._clickHandler = function (event) { @@ -394,9 +442,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); - } + this._triggerEvent('nodeExpanded', node); } else if (!state) { @@ -419,9 +465,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); - } + this._triggerEvent('nodeCollapsed', node); } }; @@ -487,9 +531,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeSelected', $.extend(true, {}, node)); - } + this._triggerEvent('nodeSelected', node); } else { @@ -515,9 +557,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); - } + this._triggerEvent('nodeUnselected', node); } return this; @@ -548,9 +588,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeChecked', $.extend(true, {}, node)); - } + this._triggerEvent('nodeChecked', node); } else { @@ -566,9 +604,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); - } + this._triggerEvent('nodeUnchecked', node); } }; @@ -594,9 +630,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); - } + this._triggerEvent('nodeDisabled', node); } else { @@ -609,9 +643,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); - } + this._triggerEvent('nodeEnabled', node); } }; @@ -637,7 +669,6 @@ }; Tree.prototype._render = function () { - if (!this._initialized) { // Setup first time only components @@ -657,6 +688,8 @@ node.level = 1; this._renderNode(node); }, this)); + + this._triggerEvent('rendered', this._nodes); }; Tree.prototype._renderNode = function (node, pEl) { @@ -732,12 +765,14 @@ this._renderNode(childNode, node.$el); }, this)); } + + // Trigger nodeRendered event + this._triggerEvent('nodeRendered', node); }; // Creates a new node element from template and // ensures the template is inserted at the correct position Tree.prototype._newNodeEl = function (pEl) { - var $el = $(this._template.node); if (pEl) { @@ -764,7 +799,6 @@ // Add inline style into head Tree.prototype._injectStyle = function () { - if (this._options.injectStyle && !document.getElementById(this._styleId)) { $('').appendTo('head'); } @@ -772,7 +806,6 @@ // Construct trees style based on user options Tree.prototype._buildStyle = function () { - var style = '.node-' + this._elementId + '{'; // Basic bootstrap style overrides @@ -1250,7 +1283,7 @@ this.revealNode(results); } - this.$element.trigger('searchComplete', $.extend(true, {}, results)); + this._triggerEvent('searchComplete', results); return results; }; @@ -1265,7 +1298,7 @@ this._setSearchResult(node, false, options); }, this)); - this.$element.trigger('searchCleared', $.extend(true, {}, results)); + this._triggerEvent('searchCleared', results); }; Tree.prototype._getSearchResults = function () { @@ -1290,10 +1323,8 @@ @return {Array} nodes - Nodes that match your criteria */ Tree.prototype._findNodes = function (pattern, attribute, modifier) { - attribute = attribute || 'text'; modifier = modifier || 'g'; - return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index cdd783307..78ede0e19 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -60,6 +60,11 @@ preventUnselect: false, // Event handlers + onInitialized: undefined, + onNodeRendered: undefined, + onRendered: undefined, + onDestroyed: undefined, + onNodeChecked: undefined, onNodeCollapsed: undefined, onNodeDisabled: undefined, @@ -68,6 +73,7 @@ onNodeSelected: undefined, onNodeUnchecked: undefined, onNodeUnselected: undefined, + onSearchComplete: undefined, onSearchCleared: undefined }; @@ -84,7 +90,6 @@ }; var Tree = function (element, options) { - this.$element = $(element); this._elementId = element.id; this._styleId = this._elementId + '-style'; @@ -147,7 +152,6 @@ }; Tree.prototype._init = function (options) { - this._tree = []; this._nodes = []; this._initialized = false; @@ -163,7 +167,14 @@ this._destroy(); this._subscribeEvents(); - this._setInitialStates({ nodes: this._tree }, 0); + + // index nodes + $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) + .done($.proxy(function () { + this._triggerEvent('initialized', this._nodes); + }, this)); + + // render to DOM this._render(); }; @@ -174,21 +185,24 @@ }; Tree.prototype._destroy = function () { - if (!this._initialized) return; + this._initialized = false; - this.$wrapper.remove(); - this.$wrapper = null; + this._triggerEvent('destroyed', null); // Switch off events this._unsubscribeEvents(); - // Reset this._initialized flag - this._initialized = false; + // Tear down + this.$wrapper.remove(); + this.$wrapper = null; }; Tree.prototype._unsubscribeEvents = function () { - + this.$element.off('initialized'); + this.$element.off('nodeRendered'); + this.$element.off('rendered'); + this.$element.off('destroyed'); this.$element.off('click'); this.$element.off('nodeChecked'); this.$element.off('nodeCollapsed'); @@ -203,9 +217,24 @@ }; Tree.prototype._subscribeEvents = function () { - this._unsubscribeEvents(); + if (typeof (this._options.onInitialized) === 'function') { + this.$element.on('initialized', this._options.onInitialized); + } + + if (typeof (this._options.onNodeRendered) === 'function') { + this.$element.on('nodeRendered', this._options.onNodeRendered); + } + + if (typeof (this._options.onRendered) === 'function') { + this.$element.on('rendered', this._options.onRendered); + } + + if (typeof (this._options.onDestroyed) === 'function') { + this.$element.on('destroyed', this._options.onDestroyed); + } + this.$element.on('click', $.proxy(this._clickHandler, this)); if (typeof (this._options.onNodeChecked) === 'function') { @@ -249,20 +278,29 @@ } }; + Tree.prototype._triggerEvent = function (event, data, options) { + if (!options || (options && !options.silent)) { + this.$element.trigger(event, $.extend(true, {}, data)); + } + } + /* Recurse the tree structure and ensure all nodes have valid initial states. User defined states will be preserved. For performance we also take this opportunity to index nodes in a flattened structure */ - Tree.prototype._setInitialStates = function (node, level) { + Tree.prototype._setInitialStates = function (node, level, ready) { if (!node.nodes) return; level += 1; + ready = ready || []; var parent = node; var _this = this; $.each(node.nodes, function checkStates(index, node) { + var deferred = new $.Deferred(); + ready.push(deferred.promise()); // nodeId : unique, incremental identifier node.nodeId = _this._nodes.length; @@ -319,13 +357,17 @@ // recurse child nodes and transverse the tree if (node.nodes) { if (node.nodes.length > 0) { - _this._setInitialStates(node, level); + _this._setInitialStates(node, level, ready); } else { delete node.nodes; } } + + deferred.resolve(); }); + + return ready; }; Tree.prototype._clickHandler = function (event) { @@ -394,9 +436,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); - } + this._triggerEvent('nodeExpanded', node); } else if (!state) { @@ -419,9 +459,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); - } + this._triggerEvent('nodeCollapsed', node); } }; @@ -487,9 +525,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeSelected', $.extend(true, {}, node)); - } + this._triggerEvent('nodeSelected', node); } else { @@ -515,9 +551,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); - } + this._triggerEvent('nodeUnselected', node); } return this; @@ -548,9 +582,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeChecked', $.extend(true, {}, node)); - } + this._triggerEvent('nodeChecked', node); } else { @@ -566,9 +598,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); - } + this._triggerEvent('nodeUnchecked', node); } }; @@ -594,9 +624,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); - } + this._triggerEvent('nodeDisabled', node); } else { @@ -609,9 +637,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); - } + this._triggerEvent('nodeEnabled', node); } }; @@ -637,7 +663,6 @@ }; Tree.prototype._render = function () { - if (!this._initialized) { // Setup first time only components @@ -657,6 +682,8 @@ node.level = 1; this._renderNode(node); }, this)); + + this._triggerEvent('rendered', this._nodes); }; Tree.prototype._renderNode = function (node, pEl) { @@ -732,12 +759,14 @@ this._renderNode(childNode, node.$el); }, this)); } + + // Trigger nodeRendered event + this._triggerEvent('nodeRendered', node); }; // Creates a new node element from template and // ensures the template is inserted at the correct position Tree.prototype._newNodeEl = function (pEl) { - var $el = $(this._template.node); if (pEl) { @@ -764,7 +793,6 @@ // Add inline style into head Tree.prototype._injectStyle = function () { - if (this._options.injectStyle && !document.getElementById(this._styleId)) { $('').appendTo('head'); } @@ -772,7 +800,6 @@ // Construct trees style based on user options Tree.prototype._buildStyle = function () { - var style = '.node-' + this._elementId + '{'; // Basic bootstrap style overrides @@ -1250,7 +1277,7 @@ this.revealNode(results); } - this.$element.trigger('searchComplete', $.extend(true, {}, results)); + this._triggerEvent('searchComplete', results); return results; }; @@ -1265,7 +1292,7 @@ this._setSearchResult(node, false, options); }, this)); - this.$element.trigger('searchCleared', $.extend(true, {}, results)); + this._triggerEvent('searchCleared', results); }; Tree.prototype._getSearchResults = function () { @@ -1290,10 +1317,8 @@ @return {Array} nodes - Nodes that match your criteria */ Tree.prototype._findNodes = function (pattern, attribute, modifier) { - attribute = attribute || 'text'; modifier = modifier || 'g'; - return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index cdd783307..52d532076 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -60,6 +60,17 @@ preventUnselect: false, // Event handlers + onInitialized: undefined, + onNodeRendered: undefined, + onRendered: undefined, + onDestroyed: undefined, + + // onNodeHover: undefined, + // onNodeClicked: undefined, + // onNodeDblClicked: undefined, + // onNodeContextMenuClicked: undefined, + // onNodeTagClicked: undefined, + onNodeChecked: undefined, onNodeCollapsed: undefined, onNodeDisabled: undefined, @@ -68,6 +79,7 @@ onNodeSelected: undefined, onNodeUnchecked: undefined, onNodeUnselected: undefined, + onSearchComplete: undefined, onSearchCleared: undefined }; @@ -84,7 +96,6 @@ }; var Tree = function (element, options) { - this.$element = $(element); this._elementId = element.id; this._styleId = this._elementId + '-style'; @@ -147,7 +158,6 @@ }; Tree.prototype._init = function (options) { - this._tree = []; this._nodes = []; this._initialized = false; @@ -163,7 +173,14 @@ this._destroy(); this._subscribeEvents(); - this._setInitialStates({ nodes: this._tree }, 0); + + // index nodes + $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) + .done($.proxy(function () { + this._triggerEvent('initialized', this._nodes); + }, this)); + + // render to DOM this._render(); }; @@ -174,21 +191,24 @@ }; Tree.prototype._destroy = function () { - if (!this._initialized) return; + this._initialized = false; - this.$wrapper.remove(); - this.$wrapper = null; + this._triggerEvent('destroyed', null); // Switch off events this._unsubscribeEvents(); - // Reset this._initialized flag - this._initialized = false; + // Tear down + this.$wrapper.remove(); + this.$wrapper = null; }; Tree.prototype._unsubscribeEvents = function () { - + this.$element.off('initialized'); + this.$element.off('nodeRendered'); + this.$element.off('rendered'); + this.$element.off('destroyed'); this.$element.off('click'); this.$element.off('nodeChecked'); this.$element.off('nodeCollapsed'); @@ -203,9 +223,24 @@ }; Tree.prototype._subscribeEvents = function () { - this._unsubscribeEvents(); + if (typeof (this._options.onInitialized) === 'function') { + this.$element.on('initialized', this._options.onInitialized); + } + + if (typeof (this._options.onNodeRendered) === 'function') { + this.$element.on('nodeRendered', this._options.onNodeRendered); + } + + if (typeof (this._options.onRendered) === 'function') { + this.$element.on('rendered', this._options.onRendered); + } + + if (typeof (this._options.onDestroyed) === 'function') { + this.$element.on('destroyed', this._options.onDestroyed); + } + this.$element.on('click', $.proxy(this._clickHandler, this)); if (typeof (this._options.onNodeChecked) === 'function') { @@ -249,20 +284,29 @@ } }; + Tree.prototype._triggerEvent = function (event, data, options) { + if (!options || (options && !options.silent)) { + this.$element.trigger(event, $.extend(true, {}, data)); + } + } + /* Recurse the tree structure and ensure all nodes have valid initial states. User defined states will be preserved. For performance we also take this opportunity to index nodes in a flattened structure */ - Tree.prototype._setInitialStates = function (node, level) { + Tree.prototype._setInitialStates = function (node, level, ready) { if (!node.nodes) return; level += 1; + ready = ready || []; var parent = node; var _this = this; $.each(node.nodes, function checkStates(index, node) { + var deferred = new $.Deferred(); + ready.push(deferred.promise()); // nodeId : unique, incremental identifier node.nodeId = _this._nodes.length; @@ -319,13 +363,17 @@ // recurse child nodes and transverse the tree if (node.nodes) { if (node.nodes.length > 0) { - _this._setInitialStates(node, level); + _this._setInitialStates(node, level, ready); } else { delete node.nodes; } } + + deferred.resolve(); }); + + return ready; }; Tree.prototype._clickHandler = function (event) { @@ -394,9 +442,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); - } + this._triggerEvent('nodeExpanded', node); } else if (!state) { @@ -419,9 +465,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); - } + this._triggerEvent('nodeCollapsed', node); } }; @@ -487,9 +531,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeSelected', $.extend(true, {}, node)); - } + this._triggerEvent('nodeSelected', node); } else { @@ -515,9 +557,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); - } + this._triggerEvent('nodeUnselected', node); } return this; @@ -548,9 +588,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeChecked', $.extend(true, {}, node)); - } + this._triggerEvent('nodeChecked', node); } else { @@ -566,9 +604,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); - } + this._triggerEvent('nodeUnchecked', node); } }; @@ -594,9 +630,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); - } + this._triggerEvent('nodeDisabled', node); } else { @@ -609,9 +643,7 @@ } // Optionally trigger event - if (options && !options.silent) { - this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); - } + this._triggerEvent('nodeEnabled', node); } }; @@ -637,7 +669,6 @@ }; Tree.prototype._render = function () { - if (!this._initialized) { // Setup first time only components @@ -657,6 +688,8 @@ node.level = 1; this._renderNode(node); }, this)); + + this._triggerEvent('rendered', this._nodes); }; Tree.prototype._renderNode = function (node, pEl) { @@ -732,12 +765,14 @@ this._renderNode(childNode, node.$el); }, this)); } + + // Trigger nodeRendered event + this._triggerEvent('nodeRendered', node); }; // Creates a new node element from template and // ensures the template is inserted at the correct position Tree.prototype._newNodeEl = function (pEl) { - var $el = $(this._template.node); if (pEl) { @@ -764,7 +799,6 @@ // Add inline style into head Tree.prototype._injectStyle = function () { - if (this._options.injectStyle && !document.getElementById(this._styleId)) { $('').appendTo('head'); } @@ -772,7 +806,6 @@ // Construct trees style based on user options Tree.prototype._buildStyle = function () { - var style = '.node-' + this._elementId + '{'; // Basic bootstrap style overrides @@ -1250,7 +1283,7 @@ this.revealNode(results); } - this.$element.trigger('searchComplete', $.extend(true, {}, results)); + this._triggerEvent('searchComplete', results); return results; }; @@ -1265,7 +1298,7 @@ this._setSearchResult(node, false, options); }, this)); - this.$element.trigger('searchCleared', $.extend(true, {}, results)); + this._triggerEvent('searchCleared', results); }; Tree.prototype._getSearchResults = function () { @@ -1290,10 +1323,8 @@ @return {Array} nodes - Nodes that match your criteria */ Tree.prototype._findNodes = function (pattern, attribute, modifier) { - attribute = attribute || 'text'; modifier = modifier || 'g'; - return $.grep(this._nodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { diff --git a/tests/tests.js b/tests/tests.js index 62bb8ad24..83c5838bc 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -111,6 +111,10 @@ equal(options.showTags, false, 'showTags default ok'); equal(options.multiSelect, false, 'multiSelect default ok'); equal(options.preventUnselect, false, 'preventUnselect default ok'); + equal(options.onInitialized, null, 'onInitialized default ok'); + equal(options.onNodeRendered, null, 'onNodeRendered default ok'); + equal(options.onRendered, null, 'onRendered default ok'); + equal(options.onDestroyed, null, 'onDestroyed default ok'); equal(options.onNodeChecked, null, 'onNodeChecked default ok'); equal(options.onNodeCollapsed, null, 'onNodeCollapsed default ok'); equal(options.onNodeDisabled, null, 'onNodeDisabled default ok'); @@ -148,6 +152,10 @@ showTags: true, multiSelect: true, preventUnselect: true, + onInitialized: function () {}, + onNodeRendered: function () {}, + onRendered: function () {}, + onDestroyed: function () {}, onNodeChecked: function () {}, onNodeCollapsed: function () {}, onNodeDisabled: function () {}, @@ -186,6 +194,10 @@ equal(options.showTags, true, 'showTags set ok'); equal(options.multiSelect, true, 'multiSelect set ok'); equal(options.preventUnselect, true, 'preventUnselect set ok'); + equal(typeof options.onInitialized, 'function', 'onInitialized set ok'); + equal(typeof options.onNodeRendered, 'function', 'onNodeRendered set ok'); + equal(typeof options.onRendered, 'function', 'onRendered set ok'); + equal(typeof options.onDestroyed, 'function', 'onDestroyed set ok'); equal(typeof options.onNodeChecked, 'function', 'onNodeChecked set ok'); equal(typeof options.onNodeCollapsed, 'function', 'onNodeCollapsed set ok'); equal(typeof options.onNodeDisabled, 'function', 'onNodeDisabled set ok'); @@ -836,4 +848,28 @@ ok(onWorked, 'searchCleared was fired'); }); + + module('Events'); + + test('Lifecycle Events', function () { + var cbInitialized = false; + var cbNodeRendered = false; + var cbRendered = false; + var cbDestroyed = false; + var $tree = init({ + data: data, + onInitialized: function(/*event, results*/) { cbInitialized = true; }, + onNodeRendered: function(/*event, results*/) { cbNodeRendered = true; }, + onRendered: function(/*event, results*/) { cbRendered = true; }, + onDestroyed: function(/*event, results*/) { cbDestroyed = true; } + }) + .treeview(true) + .remove(); + + ok(cbInitialized, 'onInitialized triggered'); + ok(cbNodeRendered, 'onNodeRendered triggered'); + ok(cbRendered, 'onRendered triggered'); + ok(cbDestroyed, 'onDestroyed triggered'); + }); + }()); From 0d4b880aba8218023a638c2ffcc479cb0472414c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Thu, 2 Jun 2016 19:52:12 +0100 Subject: [PATCH 32/52] Fix missing event options to silence events during initialization --- dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 30 +++++++++++++++--------------- src/js/bootstrap-treeview.js | 30 +++++++++++++++--------------- tests/lib/bootstrap-treeview.js | 30 +++++++++++++++--------------- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 23ff8c014..9d8d6f119 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),a.when.apply(this,this._setInitialStates({nodes:this._tree},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes)},this)),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){(!d||d&&!d.silent)&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                              ',node:'
                                                                                                            • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),a.when.apply(this,this._setInitialStates({nodes:this._tree},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this)),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                ',node:'
                                                                                                              • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 52d532076..1b513ba5a 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -177,7 +177,7 @@ // index nodes $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes); + this._triggerEvent('initialized', this._nodes, _default.options); }, this)); // render to DOM @@ -194,7 +194,7 @@ if (!this._initialized) return; this._initialized = false; - this._triggerEvent('destroyed', null); + this._triggerEvent('destroyed', null, _default.options); // Switch off events this._unsubscribeEvents(); @@ -285,7 +285,7 @@ }; Tree.prototype._triggerEvent = function (event, data, options) { - if (!options || (options && !options.silent)) { + if (options && !options.silent) { this.$element.trigger(event, $.extend(true, {}, data)); } } @@ -442,7 +442,7 @@ } // Optionally trigger event - this._triggerEvent('nodeExpanded', node); + this._triggerEvent('nodeExpanded', node, options); } else if (!state) { @@ -465,7 +465,7 @@ } // Optionally trigger event - this._triggerEvent('nodeCollapsed', node); + this._triggerEvent('nodeCollapsed', node, options); } }; @@ -531,7 +531,7 @@ } // Optionally trigger event - this._triggerEvent('nodeSelected', node); + this._triggerEvent('nodeSelected', node, options); } else { @@ -557,7 +557,7 @@ } // Optionally trigger event - this._triggerEvent('nodeUnselected', node); + this._triggerEvent('nodeUnselected', node, options); } return this; @@ -588,7 +588,7 @@ } // Optionally trigger event - this._triggerEvent('nodeChecked', node); + this._triggerEvent('nodeChecked', node, options); } else { @@ -604,7 +604,7 @@ } // Optionally trigger event - this._triggerEvent('nodeUnchecked', node); + this._triggerEvent('nodeUnchecked', node, options); } }; @@ -630,7 +630,7 @@ } // Optionally trigger event - this._triggerEvent('nodeDisabled', node); + this._triggerEvent('nodeDisabled', node, options); } else { @@ -643,7 +643,7 @@ } // Optionally trigger event - this._triggerEvent('nodeEnabled', node); + this._triggerEvent('nodeEnabled', node, options); } }; @@ -689,7 +689,7 @@ this._renderNode(node); }, this)); - this._triggerEvent('rendered', this._nodes); + this._triggerEvent('rendered', this._nodes, _default.options); }; Tree.prototype._renderNode = function (node, pEl) { @@ -767,7 +767,7 @@ } // Trigger nodeRendered event - this._triggerEvent('nodeRendered', node); + this._triggerEvent('nodeRendered', node, _default.options); }; // Creates a new node element from template and @@ -1283,7 +1283,7 @@ this.revealNode(results); } - this._triggerEvent('searchComplete', results); + this._triggerEvent('searchComplete', results, options); return results; }; @@ -1298,7 +1298,7 @@ this._setSearchResult(node, false, options); }, this)); - this._triggerEvent('searchCleared', results); + this._triggerEvent('searchCleared', results, options); }; Tree.prototype._getSearchResults = function () { diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 78ede0e19..a3315c879 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -171,7 +171,7 @@ // index nodes $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes); + this._triggerEvent('initialized', this._nodes, _default.options); }, this)); // render to DOM @@ -188,7 +188,7 @@ if (!this._initialized) return; this._initialized = false; - this._triggerEvent('destroyed', null); + this._triggerEvent('destroyed', null, _default.options); // Switch off events this._unsubscribeEvents(); @@ -279,7 +279,7 @@ }; Tree.prototype._triggerEvent = function (event, data, options) { - if (!options || (options && !options.silent)) { + if (options && !options.silent) { this.$element.trigger(event, $.extend(true, {}, data)); } } @@ -436,7 +436,7 @@ } // Optionally trigger event - this._triggerEvent('nodeExpanded', node); + this._triggerEvent('nodeExpanded', node, options); } else if (!state) { @@ -459,7 +459,7 @@ } // Optionally trigger event - this._triggerEvent('nodeCollapsed', node); + this._triggerEvent('nodeCollapsed', node, options); } }; @@ -525,7 +525,7 @@ } // Optionally trigger event - this._triggerEvent('nodeSelected', node); + this._triggerEvent('nodeSelected', node, options); } else { @@ -551,7 +551,7 @@ } // Optionally trigger event - this._triggerEvent('nodeUnselected', node); + this._triggerEvent('nodeUnselected', node, options); } return this; @@ -582,7 +582,7 @@ } // Optionally trigger event - this._triggerEvent('nodeChecked', node); + this._triggerEvent('nodeChecked', node, options); } else { @@ -598,7 +598,7 @@ } // Optionally trigger event - this._triggerEvent('nodeUnchecked', node); + this._triggerEvent('nodeUnchecked', node, options); } }; @@ -624,7 +624,7 @@ } // Optionally trigger event - this._triggerEvent('nodeDisabled', node); + this._triggerEvent('nodeDisabled', node, options); } else { @@ -637,7 +637,7 @@ } // Optionally trigger event - this._triggerEvent('nodeEnabled', node); + this._triggerEvent('nodeEnabled', node, options); } }; @@ -683,7 +683,7 @@ this._renderNode(node); }, this)); - this._triggerEvent('rendered', this._nodes); + this._triggerEvent('rendered', this._nodes, _default.options); }; Tree.prototype._renderNode = function (node, pEl) { @@ -761,7 +761,7 @@ } // Trigger nodeRendered event - this._triggerEvent('nodeRendered', node); + this._triggerEvent('nodeRendered', node, _default.options); }; // Creates a new node element from template and @@ -1277,7 +1277,7 @@ this.revealNode(results); } - this._triggerEvent('searchComplete', results); + this._triggerEvent('searchComplete', results, options); return results; }; @@ -1292,7 +1292,7 @@ this._setSearchResult(node, false, options); }, this)); - this._triggerEvent('searchCleared', results); + this._triggerEvent('searchCleared', results, options); }; Tree.prototype._getSearchResults = function () { diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 52d532076..1b513ba5a 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -177,7 +177,7 @@ // index nodes $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes); + this._triggerEvent('initialized', this._nodes, _default.options); }, this)); // render to DOM @@ -194,7 +194,7 @@ if (!this._initialized) return; this._initialized = false; - this._triggerEvent('destroyed', null); + this._triggerEvent('destroyed', null, _default.options); // Switch off events this._unsubscribeEvents(); @@ -285,7 +285,7 @@ }; Tree.prototype._triggerEvent = function (event, data, options) { - if (!options || (options && !options.silent)) { + if (options && !options.silent) { this.$element.trigger(event, $.extend(true, {}, data)); } } @@ -442,7 +442,7 @@ } // Optionally trigger event - this._triggerEvent('nodeExpanded', node); + this._triggerEvent('nodeExpanded', node, options); } else if (!state) { @@ -465,7 +465,7 @@ } // Optionally trigger event - this._triggerEvent('nodeCollapsed', node); + this._triggerEvent('nodeCollapsed', node, options); } }; @@ -531,7 +531,7 @@ } // Optionally trigger event - this._triggerEvent('nodeSelected', node); + this._triggerEvent('nodeSelected', node, options); } else { @@ -557,7 +557,7 @@ } // Optionally trigger event - this._triggerEvent('nodeUnselected', node); + this._triggerEvent('nodeUnselected', node, options); } return this; @@ -588,7 +588,7 @@ } // Optionally trigger event - this._triggerEvent('nodeChecked', node); + this._triggerEvent('nodeChecked', node, options); } else { @@ -604,7 +604,7 @@ } // Optionally trigger event - this._triggerEvent('nodeUnchecked', node); + this._triggerEvent('nodeUnchecked', node, options); } }; @@ -630,7 +630,7 @@ } // Optionally trigger event - this._triggerEvent('nodeDisabled', node); + this._triggerEvent('nodeDisabled', node, options); } else { @@ -643,7 +643,7 @@ } // Optionally trigger event - this._triggerEvent('nodeEnabled', node); + this._triggerEvent('nodeEnabled', node, options); } }; @@ -689,7 +689,7 @@ this._renderNode(node); }, this)); - this._triggerEvent('rendered', this._nodes); + this._triggerEvent('rendered', this._nodes, _default.options); }; Tree.prototype._renderNode = function (node, pEl) { @@ -767,7 +767,7 @@ } // Trigger nodeRendered event - this._triggerEvent('nodeRendered', node); + this._triggerEvent('nodeRendered', node, _default.options); }; // Creates a new node element from template and @@ -1283,7 +1283,7 @@ this.revealNode(results); } - this._triggerEvent('searchComplete', results); + this._triggerEvent('searchComplete', results, options); return results; }; @@ -1298,7 +1298,7 @@ this._setSearchResult(node, false, options); }, this)); - this._triggerEvent('searchCleared', results); + this._triggerEvent('searchCleared', results, options); }; Tree.prototype._getSearchResults = function () { From 72fcea368d35f993453b6bc8fc969e7982ac111f Mon Sep 17 00:00:00 2001 From: jonmiles Date: Thu, 2 Jun 2016 20:34:58 +0100 Subject: [PATCH 33/52] Add lifecycle event demo --- public/index.html | 104 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/public/index.html b/public/index.html index 34474c081..b0b9e7486 100644 --- a/public/index.html +++ b/public/index.html @@ -12,43 +12,43 @@

                                                                                                                Bootstrap Tree View

                                                                                                                Default

                                                                                                                -
                                                                                                                +

                                                                                                                Collapsed

                                                                                                                -
                                                                                                                +

                                                                                                                Expanded

                                                                                                                -
                                                                                                                +

                                                                                                                Blue Theme

                                                                                                                -
                                                                                                                +

                                                                                                                Custom Icons

                                                                                                                -
                                                                                                                +

                                                                                                                Tags as Badges

                                                                                                                -
                                                                                                                +

                                                                                                                No Border

                                                                                                                -
                                                                                                                +

                                                                                                                Colourful

                                                                                                                -
                                                                                                                +

                                                                                                                Node Overrides

                                                                                                                -
                                                                                                                +
                                                                                                                @@ -85,7 +85,7 @@

                                                                                                                Input

                                                                                                                Tree

                                                                                                                -
                                                                                                                +

                                                                                                                Results

                                                                                                                @@ -125,7 +125,7 @@

                                                                                                                Input

                                                                                                                Tree

                                                                                                                -
                                                                                                                +

                                                                                                                Events

                                                                                                                @@ -180,7 +180,7 @@

                                                                                                                Input

                                                                                                                Tree

                                                                                                                -
                                                                                                                +

                                                                                                                Events

                                                                                                                @@ -223,7 +223,7 @@

                                                                                                                Input

                                                                                                                Tree

                                                                                                                -
                                                                                                                +

                                                                                                                Events

                                                                                                                @@ -266,23 +266,44 @@

                                                                                                                Input

                                                                                                                Tree

                                                                                                                -
                                                                                                                +

                                                                                                                Events

                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Lifecycle Events

                                                                                                                +
                                                                                                                +

                                                                                                                Input

                                                                                                                +
                                                                                                                + +
                                                                                                                +
                                                                                                                + +
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Tree

                                                                                                                +
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Events

                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Data

                                                                                                                JSON Data

                                                                                                                -
                                                                                                                +

                                                                                                                -
                                                                                                                +

                                                                                                                @@ -724,6 +745,57 @@

                                                                                                                + var lifecycleTreeOptions = { + data: defaultData, + levels: 3, + onInitialized: function(event, nodes) { + $('#lifecycle-output').prepend('

                                                                                                                Initialized nodes

                                                                                                                '); + }, + onNodeRendered: function (event, node) { + $('#lifecycle-output').prepend('

                                                                                                                Finished rendering node : ' + node.text + '

                                                                                                                '); + if (node.text === 'Parent 1') { + node.$el.append($('L')); + } else if (node.text === 'Child 1') { + node.$el.append($('I')); + } else if (node.text === 'Grandchild 1') { + node.$el.append($('F')); + } else if (node.text === 'Grandchild 2') { + node.$el.append($('E')); + } else if (node.text === 'Child 2') { + node.$el.append($('C')); + } else if (node.text === 'Parent 2') { + node.$el.append($('Y')); + } else if (node.text === 'Parent 3') { + node.$el.append($('C')); + } else if (node.text === 'Parent 4') { + node.$el.append($('L')); + } else if (node.text === 'Parent 5') { + node.$el.append($('E')); + } + }, + onRendered: function(event, node) { + $('#lifecycle-output').prepend('

                                                                                                                Finished rendering

                                                                                                                '); + }, + onDestroyed: function (event, node) { + $('#lifecycle-output').prepend('

                                                                                                                Tree destroyed

                                                                                                                '); + } + }; + var $lifecycleTree = $('#treeview-lifecycle').treeview(lifecycleTreeOptions); + + $('#btn-init').on('click', function (e) { + $('#btn-init').prop('disabled', true); + $('#btn-remove').prop('disabled', false); + $lifecycleTree.treeview('init', lifecycleTreeOptions); + }); + + $('#btn-remove').on('click', function (e) { + $('#btn-remove').prop('disabled', true); + $('#btn-init').prop('disabled', false); + $lifecycleTree.treeview('remove'); + }); + + + var $tree = $('#treeview12').treeview({ data: json }); From e24ab95cbbfb659d40f513aed62cfa5bd4b61d6f Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 10:57:22 +0100 Subject: [PATCH 34/52] Document proposed changes i.e. dataUrl --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 46c301647..d4c75aca9 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ Options allow you to customise the treeview's default appearance and behaviour. // expanded to 5 levels // with a background color of green $('#tree').treeview({ - data: data, // data is not optional + data: data, levels: 5, backColor: 'green' }); @@ -237,9 +237,24 @@ You can pass a new options object to the treeview at any time but this will have The following is a list of all available options. #### data -Array of Objects. No default, expects data +Array of Objects. No default, expects either data or dataUrl. -This is the core data to be displayed by the tree view. +This is the core data to be displayed by the tree view. If data is provided, dataUrl will be ignored. + +#### dataUrl +jQuery Ajax settings object, [as documents here](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings). + +Accepts a set of key/value pairs that configure an Ajax request. All settings are optional, any provided will be merge with the following default configuration. + +```javascript +{ + method: 'GET', + dataType: 'json', + cache: false +} +``` + +> JSON is the only formatted accepted. #### backColor String, [any legal color value](http://www.w3schools.com/cssref/css_colors_legal.asp). Default: inherits from Bootstrap.css. From a926b4004117cd69a9f1aed02589763fe12a63ce Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 11:02:33 +0100 Subject: [PATCH 35/52] Tests --- tests/data.json | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/tests.js | 13 +++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/data.json diff --git a/tests/data.json b/tests/data.json new file mode 100644 index 000000000..ff16499ae --- /dev/null +++ b/tests/data.json @@ -0,0 +1,42 @@ +[ + { + "text": "Parent 1", + "tags": [4], + "nodes": [ + { + "text": "Child 1", + "tags": [2], + "nodes": [ + { + "text": "Grandchild 1", + "tags": [0] + }, + { + "text": "Grandchild 2", + "tags": [0] + } + ] + }, + { + "text": "Child 2", + "tags": [0] + } + ] + }, + { + "text": "Parent 2", + "tags": [0] + }, + { + "text": "Parent 3", + "tags": [0] + }, + { + "text": "Parent 4", + "tags": [0] + }, + { + "text": "Parent 5", + "tags": [0] + } +] diff --git a/tests/tests.js b/tests/tests.js index 83c5838bc..83e059e5f 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -213,10 +213,19 @@ module('Data'); - test('Accepts JSON', function () { - var el = init({levels:1,data:json}); + test('Accepts local data', function () { + var el = init({levels: 1, data: data}); equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); + }); + test('Accepts local JSON', function () { + var el = init({levels: 1, data: json}); + equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); + }); + + test('Accepts remove JSON', function () { + var el = init({levels: 1, dataUrl: {url: 'data.json'}}); + equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); }); From 5f036804d8ea538ae419a63598f3cb9852d6826a Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 13:35:24 +0100 Subject: [PATCH 36/52] Add load remote data using dataUrl and jQuery Ajax --- dist/bootstrap-treeview.min.js | 2 +- package.json | 8 ++--- public/js/bootstrap-treeview.js | 63 ++++++++++++++++++++++++++------- src/js/bootstrap-treeview.js | 63 ++++++++++++++++++++++++++------- tests/lib/bootstrap-treeview.js | 63 ++++++++++++++++++++++++++------- tests/tests.js | 14 +++++--- 6 files changed, 165 insertions(+), 48 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 9d8d6f119..38a48b83b 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this._tree=a.extend(!0,[],b.data),delete b.data),this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),a.when.apply(this,this._setInitialStates({nodes:this._tree},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this)),this._render()},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                  ',node:'
                                                                                                                • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(b){return a.when.apply(this,this._setInitialStates({nodes:b},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this))},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                    ',node:'
                                                                                                                  • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/package.json b/package.json index 31ef86ddb..cf390ea19 100644 --- a/package.json +++ b/package.json @@ -39,11 +39,11 @@ "devDependencies": { "bower": "1.3.x", "grunt": "0.4.x", - "grunt-contrib-uglify": "0.7.x", + "grunt-contrib-copy": "0.7.x", "grunt-contrib-cssmin": "0.12.x", - "grunt-contrib-qunit": "0.5.x", - "grunt-contrib-watch": "0.6.x", - "grunt-contrib-copy": "0.7.x" + "grunt-contrib-qunit": "1.2.x", + "grunt-contrib-uglify": "0.7.x", + "grunt-contrib-watch": "0.6.x" }, "keywords": [ "twitter", diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index a3315c879..0dbd34b3c 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -89,6 +89,12 @@ revealResults: true }; + _default.dataUrl = { + method: 'GET', + dataType: 'json', + cache: false + }; + var Tree = function (element, options) { this.$element = $(element); this._elementId = element.id; @@ -156,26 +162,57 @@ this._nodes = []; this._initialized = false; - if (options.data) { - if (typeof options.data === 'string') { - options.data = $.parseJSON(options.data); - } - this._tree = $.extend(true, [], options.data); - delete options.data; - } this._options = $.extend({}, _default.settings, options); this._destroy(); this._subscribeEvents(); - // index nodes - $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) - .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes, _default.options); + this._triggerEvent('loading', null, _default.options); + this._load(options) + .then($.proxy(function (data) { + // load done + return this._tree = $.extend(true, [], data); + }, this), $.proxy(function (error) { + // load fail + this._triggerEvent('loadingFailed', error, _default.options); + }, this)) + .then($.proxy(function (treeData) { + // initialize data + return $.when.apply(this, this._setInitialStates({ nodes: treeData }, 0)) + .done($.proxy(function () { + this._triggerEvent('initialized', this._nodes, _default.options); + }, this)); + }, this)) + .then($.proxy(function () { + // render to DOM + this._render(); }, this)); + }; + + Tree.prototype._load = function (options) { + var done = new $.Deferred(); + if (options.data) { + this._loadLocalData(options, done); + } else if (options.dataUrl) { + this._loadRemoteData(options, done); + } + return done.promise(); + }; + + Tree.prototype._loadRemoteData = function (options, done) { + $.ajax($.extend(true, {}, _default.dataUrl, options.dataUrl)) + .done(function (data) { + done.resolve(data); + }) + .fail(function (xhr, status, error) { + done.reject(error); + }); + }; - // render to DOM - this._render(); + Tree.prototype._loadLocalData = function (options, done) { + done.resolve((typeof options.data === 'string') ? + $.parseJSON(options.data) : + $.extend(true, [], options.data)); }; Tree.prototype._remove = function () { diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index a3315c879..0dbd34b3c 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -89,6 +89,12 @@ revealResults: true }; + _default.dataUrl = { + method: 'GET', + dataType: 'json', + cache: false + }; + var Tree = function (element, options) { this.$element = $(element); this._elementId = element.id; @@ -156,26 +162,57 @@ this._nodes = []; this._initialized = false; - if (options.data) { - if (typeof options.data === 'string') { - options.data = $.parseJSON(options.data); - } - this._tree = $.extend(true, [], options.data); - delete options.data; - } this._options = $.extend({}, _default.settings, options); this._destroy(); this._subscribeEvents(); - // index nodes - $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) - .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes, _default.options); + this._triggerEvent('loading', null, _default.options); + this._load(options) + .then($.proxy(function (data) { + // load done + return this._tree = $.extend(true, [], data); + }, this), $.proxy(function (error) { + // load fail + this._triggerEvent('loadingFailed', error, _default.options); + }, this)) + .then($.proxy(function (treeData) { + // initialize data + return $.when.apply(this, this._setInitialStates({ nodes: treeData }, 0)) + .done($.proxy(function () { + this._triggerEvent('initialized', this._nodes, _default.options); + }, this)); + }, this)) + .then($.proxy(function () { + // render to DOM + this._render(); }, this)); + }; + + Tree.prototype._load = function (options) { + var done = new $.Deferred(); + if (options.data) { + this._loadLocalData(options, done); + } else if (options.dataUrl) { + this._loadRemoteData(options, done); + } + return done.promise(); + }; + + Tree.prototype._loadRemoteData = function (options, done) { + $.ajax($.extend(true, {}, _default.dataUrl, options.dataUrl)) + .done(function (data) { + done.resolve(data); + }) + .fail(function (xhr, status, error) { + done.reject(error); + }); + }; - // render to DOM - this._render(); + Tree.prototype._loadLocalData = function (options, done) { + done.resolve((typeof options.data === 'string') ? + $.parseJSON(options.data) : + $.extend(true, [], options.data)); }; Tree.prototype._remove = function () { diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index a3315c879..0dbd34b3c 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -89,6 +89,12 @@ revealResults: true }; + _default.dataUrl = { + method: 'GET', + dataType: 'json', + cache: false + }; + var Tree = function (element, options) { this.$element = $(element); this._elementId = element.id; @@ -156,26 +162,57 @@ this._nodes = []; this._initialized = false; - if (options.data) { - if (typeof options.data === 'string') { - options.data = $.parseJSON(options.data); - } - this._tree = $.extend(true, [], options.data); - delete options.data; - } this._options = $.extend({}, _default.settings, options); this._destroy(); this._subscribeEvents(); - // index nodes - $.when.apply(this, this._setInitialStates({ nodes: this._tree }, 0)) - .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes, _default.options); + this._triggerEvent('loading', null, _default.options); + this._load(options) + .then($.proxy(function (data) { + // load done + return this._tree = $.extend(true, [], data); + }, this), $.proxy(function (error) { + // load fail + this._triggerEvent('loadingFailed', error, _default.options); + }, this)) + .then($.proxy(function (treeData) { + // initialize data + return $.when.apply(this, this._setInitialStates({ nodes: treeData }, 0)) + .done($.proxy(function () { + this._triggerEvent('initialized', this._nodes, _default.options); + }, this)); + }, this)) + .then($.proxy(function () { + // render to DOM + this._render(); }, this)); + }; + + Tree.prototype._load = function (options) { + var done = new $.Deferred(); + if (options.data) { + this._loadLocalData(options, done); + } else if (options.dataUrl) { + this._loadRemoteData(options, done); + } + return done.promise(); + }; + + Tree.prototype._loadRemoteData = function (options, done) { + $.ajax($.extend(true, {}, _default.dataUrl, options.dataUrl)) + .done(function (data) { + done.resolve(data); + }) + .fail(function (xhr, status, error) { + done.reject(error); + }); + }; - // render to DOM - this._render(); + Tree.prototype._loadLocalData = function (options, done) { + done.resolve((typeof options.data === 'string') ? + $.parseJSON(options.data) : + $.extend(true, [], options.data)); }; Tree.prototype._remove = function () { diff --git a/tests/tests.js b/tests/tests.js index 83e059e5f..a4797b6c2 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -223,9 +223,15 @@ equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); }); - test('Accepts remove JSON', function () { - var el = init({levels: 1, dataUrl: {url: 'data.json'}}); - equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); + asyncTest('Accepts remote JSON', function (assert) { + var el = init({ + levels: 1, + dataUrl: {url: 'data.json'}, + onRendered: function () { + assert.equal($(el.selector + ' ul li:not(.node-hidden)').length, 5, 'Correct number of root nodes'); + start(); + } + }); }); @@ -233,7 +239,7 @@ test('Is chainable', function () { var el = init(); - equal(el.addClass('test').attr('class'), 'treeview test', 'Is chainable'); + equal(el.addClass('test').attr('class'), 'test', 'Is chainable'); }); test('Correct initial levels shown', function () { From ddd50b19c418c35f778834de190198d9dd08b62c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 13:36:19 +0100 Subject: [PATCH 37/52] Update demo examples to include loading remote data --- public/data.json | 42 ++++++++++++++++++++++++++++++++++++++++++ public/index.html | 19 ++++++++++++------- 2 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 public/data.json diff --git a/public/data.json b/public/data.json new file mode 100644 index 000000000..ff16499ae --- /dev/null +++ b/public/data.json @@ -0,0 +1,42 @@ +[ + { + "text": "Parent 1", + "tags": [4], + "nodes": [ + { + "text": "Child 1", + "tags": [2], + "nodes": [ + { + "text": "Grandchild 1", + "tags": [0] + }, + { + "text": "Grandchild 2", + "tags": [0] + } + ] + }, + { + "text": "Child 2", + "tags": [0] + } + ] + }, + { + "text": "Parent 2", + "tags": [0] + }, + { + "text": "Parent 3", + "tags": [0] + }, + { + "text": "Parent 4", + "tags": [0] + }, + { + "text": "Parent 5", + "tags": [0] + } +] diff --git a/public/index.html b/public/index.html index b0b9e7486..f187807bc 100644 --- a/public/index.html +++ b/public/index.html @@ -296,18 +296,17 @@

                                                                                                                    Events


                                                                                                                    -

                                                                                                                    Data

                                                                                                                    +

                                                                                                                    Data Options

                                                                                                                    -

                                                                                                                    JSON Data

                                                                                                                    -
                                                                                                                    +

                                                                                                                    Local JSON

                                                                                                                    +
                                                                                                                    -

                                                                                                                    -
                                                                                                                    +

                                                                                                                    Remote JSON

                                                                                                                    +

                                                                                                                    -

                                                                                                                    @@ -796,9 +795,15 @@

                                                                                                                    - var $tree = $('#treeview12').treeview({ + var $jsonTree = $('#treeview-json').treeview({ data: json }); + + var $ajaxTree = $('#treeview-ajax').treeview({ + dataUrl: { + url: './data.json' + } + }); }); From 602a9de42e96e8c607c7cc6adab3d39dfa295ef1 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 14:05:58 +0100 Subject: [PATCH 38/52] Update lifecycle events to include new events: loading, loadingFailed --- README.md | 4 +++ dist/bootstrap-treeview.min.js | 2 +- public/index.html | 3 ++ public/js/bootstrap-treeview.js | 12 +++++++ src/js/bootstrap-treeview.js | 12 +++++++ tests/lib/bootstrap-treeview.js | 12 +++++++ tests/tests.js | 55 +++++++++++++++++++++++++-------- 7 files changed, 86 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d4c75aca9..e27148de1 100644 --- a/README.md +++ b/README.md @@ -757,6 +757,10 @@ $('#tree').on('nodeSelected', function(event, data) { > Use callback handlers for lifecycle events otherwise you'll miss the events fired during creation. +`loading (event)` - The tree has initiated data loading. + +`loadingFailed (event, error)` - The tree failed to load data (ajax error) + `initialized (event, nodes)` - The tree has initialized itself and data ready for rendering. `nodeRendered (event, node)` - A new node is rendered; diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index 38a48b83b..bc20ac25f 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(b){return a.when.apply(this,this._setInitialStates({nodes:b},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this))},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                      ',node:'
                                                                                                                    • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(b){return a.when.apply(this,this._setInitialStates({nodes:b},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this))},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                        ',node:'
                                                                                                                      • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/index.html b/public/index.html index f187807bc..259b2f157 100644 --- a/public/index.html +++ b/public/index.html @@ -747,6 +747,9 @@

                                                                                                                        var lifecycleTreeOptions = { data: defaultData, levels: 3, + onLoading: function(event, nodes) { + $('#lifecycle-output').prepend('

                                                                                                                        Loaded data

                                                                                                                        '); + }, onInitialized: function(event, nodes) { $('#lifecycle-output').prepend('

                                                                                                                        Initialized nodes

                                                                                                                        '); }, diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 0dbd34b3c..2d6f356f8 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -60,6 +60,8 @@ preventUnselect: false, // Event handlers + onLoading: undefined, + onLoadingFailed: undefined, onInitialized: undefined, onNodeRendered: undefined, onRendered: undefined, @@ -236,6 +238,8 @@ }; Tree.prototype._unsubscribeEvents = function () { + this.$element.off('loading'); + this.$element.off('loadingFailed'); this.$element.off('initialized'); this.$element.off('nodeRendered'); this.$element.off('rendered'); @@ -256,6 +260,14 @@ Tree.prototype._subscribeEvents = function () { this._unsubscribeEvents(); + if (typeof (this._options.onLoading) === 'function') { + this.$element.on('loading', this._options.onLoading); + } + + if (typeof (this._options.onLoadingFailed) === 'function') { + this.$element.on('loadingFailed', this._options.onLoadingFailed); + } + if (typeof (this._options.onInitialized) === 'function') { this.$element.on('initialized', this._options.onInitialized); } diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 0dbd34b3c..2d6f356f8 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -60,6 +60,8 @@ preventUnselect: false, // Event handlers + onLoading: undefined, + onLoadingFailed: undefined, onInitialized: undefined, onNodeRendered: undefined, onRendered: undefined, @@ -236,6 +238,8 @@ }; Tree.prototype._unsubscribeEvents = function () { + this.$element.off('loading'); + this.$element.off('loadingFailed'); this.$element.off('initialized'); this.$element.off('nodeRendered'); this.$element.off('rendered'); @@ -256,6 +260,14 @@ Tree.prototype._subscribeEvents = function () { this._unsubscribeEvents(); + if (typeof (this._options.onLoading) === 'function') { + this.$element.on('loading', this._options.onLoading); + } + + if (typeof (this._options.onLoadingFailed) === 'function') { + this.$element.on('loadingFailed', this._options.onLoadingFailed); + } + if (typeof (this._options.onInitialized) === 'function') { this.$element.on('initialized', this._options.onInitialized); } diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 0dbd34b3c..2d6f356f8 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -60,6 +60,8 @@ preventUnselect: false, // Event handlers + onLoading: undefined, + onLoadingFailed: undefined, onInitialized: undefined, onNodeRendered: undefined, onRendered: undefined, @@ -236,6 +238,8 @@ }; Tree.prototype._unsubscribeEvents = function () { + this.$element.off('loading'); + this.$element.off('loadingFailed'); this.$element.off('initialized'); this.$element.off('nodeRendered'); this.$element.off('rendered'); @@ -256,6 +260,14 @@ Tree.prototype._subscribeEvents = function () { this._unsubscribeEvents(); + if (typeof (this._options.onLoading) === 'function') { + this.$element.on('loading', this._options.onLoading); + } + + if (typeof (this._options.onLoadingFailed) === 'function') { + this.$element.on('loadingFailed', this._options.onLoadingFailed); + } + if (typeof (this._options.onInitialized) === 'function') { this.$element.on('initialized', this._options.onInitialized); } diff --git a/tests/tests.js b/tests/tests.js index a4797b6c2..88df7ed6b 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -111,6 +111,8 @@ equal(options.showTags, false, 'showTags default ok'); equal(options.multiSelect, false, 'multiSelect default ok'); equal(options.preventUnselect, false, 'preventUnselect default ok'); + equal(options.onLoading, null, 'onLoading default ok'); + equal(options.onLoadingFailed, null, 'onLoadingFailed default ok'); equal(options.onInitialized, null, 'onInitialized default ok'); equal(options.onNodeRendered, null, 'onNodeRendered default ok'); equal(options.onRendered, null, 'onRendered default ok'); @@ -152,6 +154,8 @@ showTags: true, multiSelect: true, preventUnselect: true, + onLoading: function () {}, + onLoadingFailed: function () {}, onInitialized: function () {}, onNodeRendered: function () {}, onRendered: function () {}, @@ -194,6 +198,8 @@ equal(options.showTags, true, 'showTags set ok'); equal(options.multiSelect, true, 'multiSelect set ok'); equal(options.preventUnselect, true, 'preventUnselect set ok'); + equal(typeof options.onLoading, 'function', 'onLoading set ok'); + equal(typeof options.onLoadingFailed, 'function', 'onLoadingFailed set ok'); equal(typeof options.onInitialized, 'function', 'onInitialized set ok'); equal(typeof options.onNodeRendered, 'function', 'onNodeRendered set ok'); equal(typeof options.onRendered, 'function', 'onRendered set ok'); @@ -866,25 +872,48 @@ module('Events'); - test('Lifecycle Events', function () { - var cbInitialized = false; - var cbNodeRendered = false; - var cbRendered = false; - var cbDestroyed = false; + asyncTest('Lifecycle Events', function (assert) { + expect(5); + + var nodeRenderedTriggered = false; var $tree = init({ data: data, - onInitialized: function(/*event, results*/) { cbInitialized = true; }, - onNodeRendered: function(/*event, results*/) { cbNodeRendered = true; }, - onRendered: function(/*event, results*/) { cbRendered = true; }, - onDestroyed: function(/*event, results*/) { cbDestroyed = true; } + onLoading: function(/*event, results*/) { + ok(true, 'onLoading triggered'); + }, + onInitialized: function(/*event, results*/) { + ok(true, 'onLoading triggered'); + }, + onNodeRendered: function(/*event, results*/) { + // nodeRendered triggers per node + if (!nodeRenderedTriggered) { + nodeRenderedTriggered = true; + ok(true, 'onLoading triggered'); + } + }, + onRendered: function(/*event, results*/) { + ok(true, 'onLoading triggered'); + }, + onDestroyed: function(/*event, results*/) { + ok(true, 'onLoading triggered'); + start() + } }) .treeview(true) .remove(); + }); + + asyncTest('Loading Failed Event', function (assert) { + expect(1); - ok(cbInitialized, 'onInitialized triggered'); - ok(cbNodeRendered, 'onNodeRendered triggered'); - ok(cbRendered, 'onRendered triggered'); - ok(cbDestroyed, 'onDestroyed triggered'); + var $tree = init({ + dataUrl: {url: 'no.json'}, + onLoadingFailed: function(/*event, results*/) { + ok(true, 'onLoadingFailed triggered'); + start(); + } + }) + .treeview(true); }); }()); From 88c936bb2f9a4d8208219de1dc3134539bfdc198 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 14:07:45 +0100 Subject: [PATCH 39/52] Tidy --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e27148de1..3ee5c1073 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ Array of Objects. No default, expects either data or dataUrl. This is the core data to be displayed by the tree view. If data is provided, dataUrl will be ignored. #### dataUrl -jQuery Ajax settings object, [as documents here](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings). +jQuery Ajax settings object, [as documented here](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings). Accepts a set of key/value pairs that configure an Ajax request. All settings are optional, any provided will be merge with the following default configuration. @@ -254,7 +254,7 @@ Accepts a set of key/value pairs that configure an Ajax request. All settings a } ``` -> JSON is the only formatted accepted. +> JSON is the only format accepted. #### backColor String, [any legal color value](http://www.w3schools.com/cssref/css_colors_legal.asp). Default: inherits from Bootstrap.css. From c4c75642f0abfa84f2afa3843c5f71b5a17db01c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 16:05:40 +0100 Subject: [PATCH 40/52] Documented proposed changes --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/README.md b/README.md index 3ee5c1073..4ee1b612d 100644 --- a/README.md +++ b/README.md @@ -377,6 +377,7 @@ String, class names(s). Default: "glyphicon glyphicon-unchecked" as defined by Sets the icon to be as an unchecked checkbox, used in conjunction with showCheckbox. + ## Methods Methods provide a way of interacting with the plugin programmatically. For example, expanding a node is possible via the expandNode method. @@ -408,10 +409,49 @@ $('#tree').data('treeview') ``` > A better approach, if you plan a lot of interaction. + ### List of Methods The following is a list of all available methods. +#### addNode(nodes, parentNode, index, options) + +Add / append nodes to the tree. + +```javascript +$('#tree').treeview('addNode', [ nodes, parentNode, index, { silent: true } ]); +``` + +> If parentNode evaluates to false, node will be added to root + +> If index evaluates to false, node will be appended to the nodes + +Triggers `nodeRendered` event; pass silent to suppress events. + +#### addNodeAfter(nodes, node, options) + +Add nodes to the tree after given node. + +```javascript +$('#tree').treeview('addNodeAfter', [ nodes, node, { silent: true } ]); +``` + +> If node evaluates to false, node will be prepended to the tree's root + +Triggers `nodeRendered` event; pass silent to suppress events. + +#### addNodeBefore(nodes, node, options) + +Add nodes to the tree before given node. + +```javascript +$('#tree').treeview('addNodeAfter', [ nodes, node, { silent: true } ]); +``` + +> If node evaluates to false, node will be appended to the tree's root + +Triggers `nodeRendered` event; pass silent to suppress events. + #### checkAll(options) Checks all tree nodes @@ -618,6 +658,14 @@ Removes the tree view component. Removing attached events, internal attached obj $('#tree').treeview('remove'); ``` +#### removeNode() + +Removes given nodes from the tree. + +```javascript +$('#tree').treeview('removeNode', [ nodes, { silent: true } ]); +``` + #### revealNode(nodes, options) Reveals given tree nodes, expanding the tree from node to root. @@ -714,6 +762,16 @@ $('#tree').treeview('uncheckNode', [ nodes, { silent: true } ]); Triggers `nodeUnchecked` event; pass silent to suppress events. +#### updateNode(node, newNode, option) + +Updates / replaces a given tree node. + +```javascript +$('#tree').treeview('updateNode', [ node, newNode, { silent: true } ]); +``` + +Triggers `nodeRendered` event; pass silent to suppress events. + #### unselectNode(nodes, options) Unselects given tree nodes. @@ -724,6 +782,8 @@ $('#tree').treeview('unselectNode', [ nodes, { silent: true } ]); Triggers `nodeUnselected` event; pass silent to suppress events. + + ## Events Events are provided so that your application can respond to changes in the treeview's state. For example, if you want to update a display when a node is selected use the `nodeSelected` event. From 069375fd392aa98115be9e007c356cbefbdc1a6b Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 4 Jun 2016 16:08:47 +0100 Subject: [PATCH 41/52] Add index (relative to siblings) to node properties - needed for addNodes(nodes, parentNode, index, options) --- dist/bootstrap-treeview.min.js | 2 +- public/index.html | 6 +++--- public/js/bootstrap-treeview.js | 3 +++ src/js/bootstrap-treeview.js | 3 +++ tests/lib/bootstrap-treeview.js | 3 +++ 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index bc20ac25f..e367433ea 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(b){return a.when.apply(this,this._setInitialStates({nodes:b},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this))},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                          ',node:'
                                                                                                                        • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(b){return a.when.apply(this,this._setInitialStates({nodes:b},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this))},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.index=b,g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                            ',node:'
                                                                                                                          • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/index.html b/public/index.html index 259b2f157..7dd03eb0c 100644 --- a/public/index.html +++ b/public/index.html @@ -747,7 +747,7 @@

                                                                                                                            var lifecycleTreeOptions = { data: defaultData, levels: 3, - onLoading: function(event, nodes) { + onLoading: function(event) { $('#lifecycle-output').prepend('

                                                                                                                            Loaded data

                                                                                                                            '); }, onInitialized: function(event, nodes) { @@ -775,10 +775,10 @@

                                                                                                                            node.$el.append($('E')); } }, - onRendered: function(event, node) { + onRendered: function(event, nodes) { $('#lifecycle-output').prepend('

                                                                                                                            Finished rendering

                                                                                                                            '); }, - onDestroyed: function (event, node) { + onDestroyed: function (event) { $('#lifecycle-output').prepend('

                                                                                                                            Tree destroyed

                                                                                                                            '); } }; diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 2d6f356f8..25d1ff355 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -351,6 +351,9 @@ var deferred = new $.Deferred(); ready.push(deferred.promise()); + // index : relative to siblings + node.index = index; + // nodeId : unique, incremental identifier node.nodeId = _this._nodes.length; diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 2d6f356f8..25d1ff355 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -351,6 +351,9 @@ var deferred = new $.Deferred(); ready.push(deferred.promise()); + // index : relative to siblings + node.index = index; + // nodeId : unique, incremental identifier node.nodeId = _this._nodes.length; diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 2d6f356f8..25d1ff355 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -351,6 +351,9 @@ var deferred = new $.Deferred(); ready.push(deferred.promise()); + // index : relative to siblings + node.index = index; + // nodeId : unique, incremental identifier node.nodeId = _this._nodes.length; From e2558582db579a1b003631dc487a4c2366b8831c Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 5 Jun 2016 14:32:03 +0100 Subject: [PATCH 42/52] Refactor initialisation and rendering to support proposed node method --- src/js/bootstrap-treeview.js | 136 +++++++++++++++++------------------ 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 25d1ff355..395e3bb96 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -139,7 +139,7 @@ toggleNodeExpanded: $.proxy(this.toggleNodeExpanded, this), revealNode: $.proxy(this.revealNode, this), - // Expand / collapse methods + // Check / uncheck methods checkAll: $.proxy(this.checkAll, this), checkNode: $.proxy(this.checkNode, this), uncheckAll: $.proxy(this.uncheckAll, this), @@ -161,7 +161,8 @@ Tree.prototype._init = function (options) { this._tree = []; - this._nodes = []; + this._nodes = {}; + this._orderedNodes = []; this._initialized = false; this._options = $.extend({}, _default.settings, options); @@ -180,10 +181,7 @@ }, this)) .then($.proxy(function (treeData) { // initialize data - return $.when.apply(this, this._setInitialStates({ nodes: treeData }, 0)) - .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes, _default.options); - }, this)); + return this._setInitialStates({ nodes: treeData }, 0); }, this)) .then($.proxy(function () { // render to DOM @@ -337,25 +335,37 @@ Recurse the tree structure and ensure all nodes have valid initial states. User defined states will be preserved. For performance we also take this opportunity to - index nodes in a flattened structure + index nodes in a flattened ordered structure */ - Tree.prototype._setInitialStates = function (node, level, ready) { + Tree.prototype._setInitialStates = function (node, level) { + return $.when.apply(this, this._setInitialState(node, level)) + .done($.proxy(function () { + this._orderedNodes = this._sortNodes(); + this._triggerEvent('initialized', this._orderedNodes, _default.options); + return; + }, this)); + }; + Tree.prototype._setInitialState = function (node, level, done) { if (!node.nodes) return; level += 1; - ready = ready || []; + done = done || []; var parent = node; - var _this = this; - $.each(node.nodes, function checkStates(index, node) { + $.each(node.nodes, $.proxy(function (index, node) { var deferred = new $.Deferred(); - ready.push(deferred.promise()); + done.push(deferred.promise()); + + // level : hierarchical tree level, starts at 1 + node.level = level; // index : relative to siblings node.index = index; - // nodeId : unique, incremental identifier - node.nodeId = _this._nodes.length; + // nodeId : unique, hierarchical identifier + node.nodeId = (parent && parent.nodeId) ? + parent.nodeId + '.' + node.index : + (level - 1) + '.' + node.index; // parentId : transversing up the tree node.parentId = parent.nodeId; @@ -381,7 +391,7 @@ // set expanded state; if not provided based on levels if (!node.state.hasOwnProperty('expanded')) { if (!node.state.disabled && - (level < _this._options.levels) && + (level < this._options.levels) && (node.nodes && node.nodes.length > 0)) { node.state.expanded = true; } @@ -390,36 +400,44 @@ } } - // set visible state; based purely on levels - if (level > _this._options.levels) { - node.state.visible = false; - } - else { - node.state.visible = true; - } - // set selected state; unless set always false if (!node.state.hasOwnProperty('selected')) { node.state.selected = false; } - // index nodes in a flattened structure for use later - _this._nodes.push(node); + // set visible state; based parent state plus levels + if ((parent && parent.state && parent.state.expanded) || + (level <= this._options.levels)) { + node.state.visible = true; + } + else { + node.state.visible = false; + } - // recurse child nodes and transverse the tree + // recurse child nodes and transverse the tree, depth-first if (node.nodes) { if (node.nodes.length > 0) { - _this._setInitialStates(node, level, ready); + this._setInitialState(node, level, done); } else { delete node.nodes; } } + // add / update indexed collection + this._nodes[node.nodeId] = node; + + // mark task as complete deferred.resolve(); - }); + }, this)); - return ready; + return done; + }; + + Tree.prototype._sortNodes = function () { + return $.map(Object.keys(this._nodes).sort(), $.proxy(function (value, index) { + return this._nodes[value]; + }, this)); }; Tree.prototype._clickHandler = function (event) { @@ -447,10 +465,8 @@ // Looks up the DOM for the closest parent list item to retrieve the // data attribute nodeid, which is used to lookup the node in the flattened structure. Tree.prototype.targetNode = function (target) { - - var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); + var nodeId = target.closest('li.list-group-item').attr('data-nodeId'); var node = this._nodes[nodeId]; - if (!node) { console.log('Error: node does not exist'); } @@ -728,33 +744,29 @@ this._initialized = true; } - if (!this._tree) return; - - $.each(this._tree, $.proxy(function addRootNodes(id, node) { - node.level = 1; - this._renderNode(node); + var previousNode; + $.each(this._orderedNodes, $.proxy(function (id, node) { + this._renderNode(node, previousNode); + previousNode = node; }, this)); - this._triggerEvent('rendered', this._nodes, _default.options); + this._triggerEvent('rendered', this._orderedNodes, _default.options); }; - Tree.prototype._renderNode = function (node, pEl) { + Tree.prototype._renderNode = function (node, previousNode) { if (!node) return; if (!node.$el) { - - // New node, needs a new element - node.$el = this._newNodeEl(pEl); - - // One time setup - node.$el - .addClass('node-' + this._elementId) - .attr('data-nodeid', node.nodeId); + node.$el = this._newNodeEl(node, previousNode) + .addClass('node-' + this._elementId); } else { node.$el.empty(); } + // Set / update nodeid; it can change as a result of addNode etc. + node.$el.attr('data-nodeId', node.nodeId); + // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { node.$el.append(this._template.indent); @@ -804,42 +816,30 @@ this._setDisabled(node, node.state.disabled); this._setVisible(node, node.state.visible); - // If children exist, recursively add - if (node.nodes) { - $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { - childNode.level = node.level + 1; - this._renderNode(childNode, node.$el); - }, this)); - } - // Trigger nodeRendered event this._triggerEvent('nodeRendered', node, _default.options); }; // Creates a new node element from template and // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (pEl) { + Tree.prototype._newNodeEl = function (/*$parentEl,*/ node, previousNode) { var $el = $(this._template.node); - - if (pEl) { + if (previousNode) { this.$wrapper.children() - .eq(pEl.index()).after($el); - } - else { + .eq(previousNode.$el.index()) + .after($el); + } else { this.$wrapper.append($el); } - return $el; }; // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; - - var $pEl = node.$el; $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { childNode.level = node.level + 1; - this._renderNode(childNode, $pEl); + this._renderNode(childNode, node.$el); }, this)); }; @@ -908,7 +908,7 @@ } // Node level style overrides - $.each(this._nodes, $.proxy(function (index, node) { + $.each(this._orderedNodes, $.proxy(function (index, node) { if (node.color || node.backColor) { var innerStyle = ''; if (node.color) { @@ -917,7 +917,7 @@ if (node.backColor) { innerStyle += 'background-color:' + node.backColor + ';'; } - style += '.node-' + this._elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + style += '.node-' + this._elementId + '[data-nodeId="' + node.nodeId + '"]{' + innerStyle + '}'; } }, this)); @@ -1371,7 +1371,7 @@ Tree.prototype._findNodes = function (pattern, attribute, modifier) { attribute = attribute || 'text'; modifier = modifier || 'g'; - return $.grep(this._nodes, $.proxy(function (node) { + return $.grep(this._orderedNodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); From 22172d83be84469828499037172ec46a20a2632f Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 5 Jun 2016 17:20:36 +0100 Subject: [PATCH 43/52] Implemented addNodes --- README.md | 4 +- src/js/bootstrap-treeview.js | 58 ++++++++++++- tests/tests.js | 157 ++++++++++++++++++++++++++++++++++- 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4ee1b612d..9eb30fa7c 100644 --- a/README.md +++ b/README.md @@ -416,7 +416,7 @@ The following is a list of all available methods. #### addNode(nodes, parentNode, index, options) -Add / append nodes to the tree. +Add nodes to the tree. ```javascript $('#tree').treeview('addNode', [ nodes, parentNode, index, { silent: true } ]); @@ -570,6 +570,8 @@ Returns an array of matching node objects. $('#tree').treeview('findNode', ['Parent', 'text']); ``` +> Use regular expressions for pattern matching NOT string equals, if you need to match an exact string use start and end string anchors e.g. ^pattern$. + #### getChecked() Returns an array of checked nodes e.g. state.checked = true. diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 395e3bb96..26eaf404e 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -126,6 +126,9 @@ getDisabled: $.proxy(this.getDisabled, this), getEnabled: $.proxy(this.getEnabled, this), + // Creation methods + addNode: $.proxy(this.addNode, this), + // Select methods selectNode: $.proxy(this.selectNode, this), unselectNode: $.proxy(this.unselectNode, this), @@ -822,14 +825,18 @@ // Creates a new node element from template and // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (/*$parentEl,*/ node, previousNode) { + Tree.prototype._newNodeEl = function (node, previousNode) { var $el = $(this._template.node); if (previousNode) { + // typical usage, as nodes are rendered in + // sort order we add after the previous element this.$wrapper.children() .eq(previousNode.$el.index()) .after($el); } else { - this.$wrapper.append($el); + // we use prepend instead of append, + // to cater for root inserts i.e. nodeId 0.0 + this.$wrapper.prepend($el); } return $el; }; @@ -1043,6 +1050,53 @@ }; + /** + Add nodes to the tree. + @param {Array} nodes - An array of nodes to add + @param {optional Object} parentNode - The node to which nodes will be added as children + @param {optional number} index - Zero based insert index + @param {optional Object} options + */ + Tree.prototype.addNode = function (nodes, parentNode, index, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (parentNode instanceof Array) { + parentNode = parentNode[0]; + } + + options = $.extend({}, _default.options, options); + + // identify target nodes; either the tree's root or a parent's child nodes + var targetNodes; + if (parentNode && parentNode.nodes) { + targetNodes = parentNode.nodes; + } else if (parentNode) { + targetNodes = parentNode.nodes = []; + } else { + targetNodes = this._tree; + } + + // inserting nodes at specified positions + $.each(nodes, $.proxy(function (i, node) { + var insertIndex = (typeof(index) === 'number') ? (index + i) : (targetNodes.length + 1); + targetNodes.splice(insertIndex, 0, node); + }, this)); + + // initialize new state and render changes + if (parentNode) { + this._setInitialStates(parentNode, parentNode.level); + if (!parentNode.state.expanded) { + this._setExpanded(parentNode, true, options); + } + } else { + this._setInitialStates({nodes: targetNodes}, 0); + } + this._render(); + } + + /** Selects given tree nodes @param {Array} nodes - An array of nodes diff --git a/tests/tests.js b/tests/tests.js index 88df7ed6b..b7a864419 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -46,6 +46,19 @@ } ]; + var singleNode = { + text: 'Single 1' + }; + + var multiNodes = [ + { + text: 'Multi 1' + }, + { + text: 'Multi 2' + } + ]; + var json = '[' + '{' + '"text": "Parent 1",' + @@ -539,6 +552,148 @@ module('Methods'); + asyncTest('addNode', function (assert) { + // expect(9); + var $tree, tree, parent; + + // Append single root node + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text !== singleNode.text) { + return; + } + equal(node.parentId, undefined, 'Append single root node : is root node'); + equal(node.level, 1, 'Append single root node : correct level'); + equal(node.nodeId, '0.5', 'Append single root node : correct id'); + } + }) + .treeview(true) + .addNode(singleNode); + + // Append single child node + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text !== singleNode.text) { + return; + } + equal(node.parentId, parent.nodeId, 'Append single child node : is child node'); + equal(node.level, 2, 'Append single child node : correct level'); + equal(node.nodeId, '0.0.2', 'Append single child node : correct id'); + } + }); + tree = $tree.treeview(true); + parent = tree.findNodes('Parent 1', 'text')[0]; + tree.addNode(singleNode, parent); + + // Insert single root node + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text !== singleNode.text) { + return; + } + equal(node.parentId, undefined, 'Insert single root node : is root node'); + equal(node.level, 1, 'Insert single root node : correct level'); + equal(node.nodeId, '0.0', 'Insert single root node : correct id'); + } + }); + tree = $tree.treeview(true); + tree.addNode(singleNode, null, 0); + + // Insert single child node + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text !== singleNode.text) { + return; + } + equal(node.parentId, parent.nodeId, 'Insert single child node : is child node'); + equal(node.level, 2, 'Insert single child node : correct level'); + equal(node.nodeId, '0.0.0', 'Insert single child node : correct id'); + } + }); + tree = $tree.treeview(true); + parent = tree.findNodes('Parent 1', 'text')[0]; + tree.addNode(singleNode, parent, 0); + + // Append multiple root nodes + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text === multiNodes[0].text) { + equal(node.parentId, undefined, 'Append multiple root node 1 : is root node'); + equal(node.level, 1, 'Append multiple root node 1 : correct level'); + equal(node.nodeId, '0.5', 'Append multiple root node 1 : correct id'); + } else if (node.text === multiNodes[1].text) { + equal(node.parentId, undefined, 'Append multiple root node 2 : is root node'); + equal(node.level, 1, 'Append multiple root node 2 : correct level'); + equal(node.nodeId, '0.6', 'Append multiple root node 2 : correct id'); + } + } + }) + .treeview(true) + .addNode(multiNodes); + + // Append multiple child nodes + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text === multiNodes[0].text) { + equal(node.parentId, parent.nodeId, 'Append multiple child node 1 : is child node'); + equal(node.level, 2, 'Append multiple child node 1 : correct level'); + equal(node.nodeId, '0.0.2', 'Append multiple child node 1 : correct id'); + } else if (node.text === multiNodes[1].text) { + equal(node.parentId, parent.nodeId, 'Append multiple child node 2 : is child node'); + equal(node.level, 2, 'Append multiple child node 2 : correct level'); + equal(node.nodeId, '0.0.3', 'Append multiple child node 2 : correct id'); + } + } + }) + tree = $tree.treeview(true); + parent = tree.findNodes('Parent 1', 'text')[0]; + tree.addNode(multiNodes, parent); + + // Insert multiple root nodes + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text === multiNodes[0].text) { + equal(node.parentId, undefined, 'Insert multiple root node 1 : is root node'); + equal(node.level, 1, 'Insert multiple root node 1 : correct level'); + equal(node.nodeId, '0.0', 'Insert multiple root node 1 : correct id'); + } else if (node.text === multiNodes[1].text) { + equal(node.parentId, undefined, 'Insert multiple root node 2 : is root node'); + equal(node.level, 1, 'Insert multiple root node 2 : correct level'); + equal(node.nodeId, '0.1', 'Insert multiple root node 2 : correct id'); + } + } + }) + .treeview(true) + .addNode(multiNodes, null, 0); + + // Insert multiple child nodes + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text === multiNodes[0].text) { + equal(node.parentId, parent.nodeId, 'Insert multiple child node 1 : is child node'); + equal(node.level, 2, 'Insert multiple child node 1 : correct level'); + equal(node.nodeId, '0.0.0', 'Insert multiple child node 1 : correct id'); + } else if (node.text === multiNodes[1].text) { + equal(node.parentId, parent.nodeId, 'Insert multiple child node 2 : is child node'); + equal(node.level, 2, 'Insert multiple child node 2 : correct level'); + equal(node.nodeId, '0.0.1', 'Insert multiple child node 2 : correct id'); + start(); + } + } + }) + tree = $tree.treeview(true); + parent = tree.findNodes('Parent 1', 'text')[0]; + tree.addNode(multiNodes, parent, 0); + }); + test('findNodes', function () { var tree = init({ data: data }).treeview(true); var nodeParent1 = tree.findNodes('Parent 1', 'text')[0]; @@ -896,7 +1051,7 @@ }, onDestroyed: function(/*event, results*/) { ok(true, 'onLoading triggered'); - start() + start(); } }) .treeview(true) From 8e3488817b1d78269a9eaec05b81dffd7a6b616b Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 5 Jun 2016 18:07:14 +0100 Subject: [PATCH 44/52] Implemented addNodeAfter, addNodeBefore --- src/js/bootstrap-treeview.js | 49 +++++- tests/tests.js | 296 ++++++++++++++++++++++------------- 2 files changed, 232 insertions(+), 113 deletions(-) diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index 26eaf404e..e0e78860b 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -126,8 +126,10 @@ getDisabled: $.proxy(this.getDisabled, this), getEnabled: $.proxy(this.getEnabled, this), - // Creation methods + // Tree manipulation methods addNode: $.proxy(this.addNode, this), + addNodeAfter: $.proxy(this.addNodeAfter, this), + addNodeBefore: $.proxy(this.addNodeBefore, this), // Select methods selectNode: $.proxy(this.selectNode, this), @@ -957,9 +959,16 @@ @returns {Array} nodes - An array of parent nodes */ Tree.prototype.getParents = function (nodes) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + var parentNodes = []; $.each(nodes, $.proxy(function (index, node) { - parentNodes.push(this._nodes[node.parentId]); + var parentNode = node.parentId ? this._nodes[node.parentId] : false; + if (parentNode) { + parentNodes.push(parentNode); + } }, this)); return parentNodes; }; @@ -1096,6 +1105,42 @@ this._render(); } + /** + Add nodes to the tree after given node. + @param {Array} nodes - An array of nodes to add + @param {Object} node - The node to which nodes will be added after + @param {optional Object} options + */ + Tree.prototype.addNodeAfter = function (nodes, node, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + if (node instanceof Array) { + node = node[0]; + } + options = $.extend({}, _default.options, options); + + this.addNode(nodes, this.getParents(node)[0], (node.index + 1), options); + } + + /** + Add nodes to the tree before given node. + @param {Array} nodes - An array of nodes to add + @param {Object} node - The node to which nodes will be added before + @param {optional Object} options + */ + Tree.prototype.addNodeBefore = function (nodes, node, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + if (node instanceof Array) { + node = node[0]; + } + options = $.extend({}, _default.options, options); + + this.addNode(nodes, this.getParents(node)[0], node.index, options); + } + /** Selects given tree nodes diff --git a/tests/tests.js b/tests/tests.js index b7a864419..bee288968 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -552,6 +552,125 @@ module('Methods'); + test('findNodes', function () { + var tree = init({ data: data }).treeview(true); + var nodeParent1 = tree.findNodes('Parent 1', 'text')[0]; + equal(nodeParent1.text, 'Parent 1', 'Correct node returned : requested "Parent 1", got "Parent 1"'); + }); + + test('getParents', function () { + var tree = init({ data: data }).treeview(true); + var nodeChild1 = tree.findNodes('Child 1', 'text'); + var parentNode = tree.getParents(nodeChild1)[0]; + equal(parentNode.text, 'Parent 1', 'Correct node returned : requested parent of "Child 1", got "Parent 1"'); + }); + + test('getSiblings', function () { + var tree = init({ data: data }).treeview(true); + + // Test root level, internally uses the this.tree + var nodeParent1 = tree.findNodes('Parent 1', 'text'); + var nodeParent1Siblings = tree.getSiblings(nodeParent1); + var isArray = (nodeParent1Siblings instanceof Array); + var countOK = nodeParent1Siblings.length === 4; + var resultsOK = nodeParent1Siblings[0].text === 'Parent 2'; + resultsOK = resultsOK && nodeParent1Siblings[1].text === 'Parent 3'; + resultsOK = resultsOK && nodeParent1Siblings[2].text === 'Parent 4'; + resultsOK = resultsOK && nodeParent1Siblings[3].text === 'Parent 5'; + ok(isArray, 'Correct siblings for "Parent 1" [root] : is array'); + ok(countOK, 'Correct siblings for "Parent 1" [root] : count OK'); + ok(resultsOK, 'Correct siblings for "Parent 1" [root] : results OK'); + + // Test non root level, internally uses getParent.nodes + var nodeChild1 = tree.findNodes('Child 1', 'text'); + var nodeChild1Siblings = tree.getSiblings(nodeChild1); + var isArray = (nodeChild1Siblings instanceof Array); + var countOK = nodeChild1Siblings.length === 1; + var results = nodeChild1Siblings[0].text === 'Child 2' + ok(isArray, 'Correct siblings for "Child 1" [non root] : is array'); + ok(countOK, 'Correct siblings for "Child 1" [non root] : count OK'); + ok(results, 'Correct siblings for "Child 1" [non root] : results OK'); + }); + + test('getSelected', function () { + var tree = init({ data: data }).treeview(true); + tree.selectNode(tree.findNodes('Parent 1', 'text')); + + var selectedNodes = tree.getSelected(); + ok((selectedNodes instanceof Array), 'Result is an array'); + equal(selectedNodes.length, 1, 'Correct number of nodes returned'); + equal(selectedNodes[0].text, 'Parent 1', 'Correct node returned'); + }); + + test('getUnselected', function () { + var tree = init({ data: data }).treeview(true); + tree.selectNode(tree.findNodes('Parent 1', 'text')); + + var unselectedNodes = tree.getUnselected(); + ok((unselectedNodes instanceof Array), 'Result is an array'); + equal(unselectedNodes.length, 8, 'Correct number of nodes returned'); + }); + + // Assumptions: + // Default tree + expanded to 2 levels, + // means 1 node 'Parent 1' should be expanded and therefore returned + test('getExpanded', function () { + var tree = init({ data: data }).treeview(true); + var expandedNodes = tree.getExpanded(); + ok((expandedNodes instanceof Array), 'Result is an array'); + equal(expandedNodes.length, 1, 'Correct number of nodes returned'); + equal(expandedNodes[0].text, 'Parent 1', 'Correct node returned'); + }); + + // Assumptions: + // Default tree + expanded to 2 levels, means only 'Parent 1' should be expanded + // as all other parent nodes have no children their state will be collapsed + // which means 8 of the 9 nodes should be returned + test('getCollapsed', function () { + var tree = init({ data: data }).treeview(true); + var collapsedNodes = tree.getCollapsed(); + ok((collapsedNodes instanceof Array), 'Result is an array'); + equal(collapsedNodes.length, 8, 'Correct number of nodes returned'); + }); + + test('getChecked', function () { + var tree = init({ data: data }).treeview(true); + tree.checkNode(tree.findNodes('Parent 1', 'text')); + + var checkedNodes = tree.getChecked(); + ok((checkedNodes instanceof Array), 'Result is an array'); + equal(checkedNodes.length, 1, 'Correct number of nodes returned'); + equal(checkedNodes[0].text, 'Parent 1', 'Correct node returned'); + }); + + test('getUnchecked', function () { + var tree = init({ data: data }).treeview(true); + tree.checkNode(tree.findNodes('Parent 1', 'text')); + + var uncheckedNodes = tree.getUnchecked(); + ok((uncheckedNodes instanceof Array), 'Result is an array'); + equal(uncheckedNodes.length, 8, 'Correct number of nodes returned'); + }); + + test('getDisabled', function () { + var tree = init({ data: data }).treeview(true); + tree.disableNode(tree.findNodes('Parent 1', 'text')); + + var disabledNodes = tree.getDisabled(); + ok((disabledNodes instanceof Array), 'Result is an array'); + equal(disabledNodes.length, 1, 'Correct number of nodes returned'); + equal(disabledNodes[0].text, 'Parent 1', 'Correct node returned'); + }); + + test('getEnabled', function () { + var tree = init({ data: data }).treeview(true); + tree.disableNode(tree.findNodes('Parent 1', 'text')); + + var enabledNodes = tree.getEnabled(); + ok((enabledNodes instanceof Array), 'Result is an array'); + equal(enabledNodes.length, 8, 'Correct number of nodes returned'); + }); + asyncTest('addNode', function (assert) { // expect(9); var $tree, tree, parent; @@ -694,123 +813,78 @@ tree.addNode(multiNodes, parent, 0); }); - test('findNodes', function () { - var tree = init({ data: data }).treeview(true); - var nodeParent1 = tree.findNodes('Parent 1', 'text')[0]; - equal(nodeParent1.text, 'Parent 1', 'Correct node returned : requested "Parent 1", got "Parent 1"'); - }); - - test('getParents', function () { - var tree = init({ data: data }).treeview(true); - var nodeChild1 = tree.findNodes('Child 1', 'text'); - var parentNode = tree.getParents(nodeChild1)[0]; - equal(parentNode.text, 'Parent 1', 'Correct node returned : requested parent of "Child 1", got "Parent 1"'); - }); - - test('getSiblings', function () { - var tree = init({ data: data }).treeview(true); - - // Test root level, internally uses the this.tree - var nodeParent1 = tree.findNodes('Parent 1', 'text'); - var nodeParent1Siblings = tree.getSiblings(nodeParent1); - var isArray = (nodeParent1Siblings instanceof Array); - var countOK = nodeParent1Siblings.length === 4; - var resultsOK = nodeParent1Siblings[0].text === 'Parent 2'; - resultsOK = resultsOK && nodeParent1Siblings[1].text === 'Parent 3'; - resultsOK = resultsOK && nodeParent1Siblings[2].text === 'Parent 4'; - resultsOK = resultsOK && nodeParent1Siblings[3].text === 'Parent 5'; - ok(isArray, 'Correct siblings for "Parent 1" [root] : is array'); - ok(countOK, 'Correct siblings for "Parent 1" [root] : count OK'); - ok(resultsOK, 'Correct siblings for "Parent 1" [root] : results OK'); - - // Test non root level, internally uses getParent.nodes - var nodeChild1 = tree.findNodes('Child 1', 'text'); - var nodeChild1Siblings = tree.getSiblings(nodeChild1); - var isArray = (nodeChild1Siblings instanceof Array); - var countOK = nodeChild1Siblings.length === 1; - var results = nodeChild1Siblings[0].text === 'Child 2' - ok(isArray, 'Correct siblings for "Child 1" [non root] : is array'); - ok(countOK, 'Correct siblings for "Child 1" [non root] : count OK'); - ok(results, 'Correct siblings for "Child 1" [non root] : results OK'); - }); - - test('getSelected', function () { - var tree = init({ data: data }).treeview(true); - tree.selectNode(tree.findNodes('Parent 1', 'text')); - - var selectedNodes = tree.getSelected(); - ok((selectedNodes instanceof Array), 'Result is an array'); - equal(selectedNodes.length, 1, 'Correct number of nodes returned'); - equal(selectedNodes[0].text, 'Parent 1', 'Correct node returned'); - }); - - test('getUnselected', function () { - var tree = init({ data: data }).treeview(true); - tree.selectNode(tree.findNodes('Parent 1', 'text')); - - var unselectedNodes = tree.getUnselected(); - ok((unselectedNodes instanceof Array), 'Result is an array'); - equal(unselectedNodes.length, 8, 'Correct number of nodes returned'); - }); - - // Assumptions: - // Default tree + expanded to 2 levels, - // means 1 node 'Parent 1' should be expanded and therefore returned - test('getExpanded', function () { - var tree = init({ data: data }).treeview(true); - var expandedNodes = tree.getExpanded(); - ok((expandedNodes instanceof Array), 'Result is an array'); - equal(expandedNodes.length, 1, 'Correct number of nodes returned'); - equal(expandedNodes[0].text, 'Parent 1', 'Correct node returned'); - }); - - // Assumptions: - // Default tree + expanded to 2 levels, means only 'Parent 1' should be expanded - // as all other parent nodes have no children their state will be collapsed - // which means 8 of the 9 nodes should be returned - test('getCollapsed', function () { - var tree = init({ data: data }).treeview(true); - var collapsedNodes = tree.getCollapsed(); - ok((collapsedNodes instanceof Array), 'Result is an array'); - equal(collapsedNodes.length, 8, 'Correct number of nodes returned'); - }); - - test('getChecked', function () { - var tree = init({ data: data }).treeview(true); - tree.checkNode(tree.findNodes('Parent 1', 'text')); - - var checkedNodes = tree.getChecked(); - ok((checkedNodes instanceof Array), 'Result is an array'); - equal(checkedNodes.length, 1, 'Correct number of nodes returned'); - equal(checkedNodes[0].text, 'Parent 1', 'Correct node returned'); - }); + asyncTest('addNodeAfter', function (assert) { + var $tree, tree, parent; - test('getUnchecked', function () { - var tree = init({ data: data }).treeview(true); - tree.checkNode(tree.findNodes('Parent 1', 'text')); + // Append single node after + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text !== singleNode.text) { + return; + } + equal(node.level, 1, 'Append single node after : correct level'); + equal(node.nodeId, '0.1', 'Append single node after : correct id'); + } + }); + tree = $tree.treeview(true) + parent = tree.findNodes('Parent 1', 'text'); + tree.addNodeAfter(singleNode, parent); - var uncheckedNodes = tree.getUnchecked(); - ok((uncheckedNodes instanceof Array), 'Result is an array'); - equal(uncheckedNodes.length, 8, 'Correct number of nodes returned'); + // Append multiple nodes after + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text === multiNodes[0].text) { + equal(node.level, 1, 'Append multiple nodes after 1 : correct level'); + equal(node.nodeId, '0.1', 'Append multiple nodes after 1 : correct id'); + } else if (node.text === multiNodes[1].text) { + equal(node.level, 1, 'Append multiple nodes after 2 : correct level'); + equal(node.nodeId, '0.2', 'Append multiple nodes after 2 : correct id'); + start(); + } + } + }); + tree = $tree.treeview(true) + parent = tree.findNodes('Parent 1', 'text'); + tree.addNodeAfter(multiNodes, parent); }); - test('getDisabled', function () { - var tree = init({ data: data }).treeview(true); - tree.disableNode(tree.findNodes('Parent 1', 'text')); - - var disabledNodes = tree.getDisabled(); - ok((disabledNodes instanceof Array), 'Result is an array'); - equal(disabledNodes.length, 1, 'Correct number of nodes returned'); - equal(disabledNodes[0].text, 'Parent 1', 'Correct node returned'); - }); + asyncTest('addNodeBefore', function (assert) { + var $tree, tree, parent; - test('getEnabled', function () { - var tree = init({ data: data }).treeview(true); - tree.disableNode(tree.findNodes('Parent 1', 'text')); + // Append single node before + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text !== singleNode.text) { + return; + } + equal(node.level, 1, 'Append single node before : correct level'); + equal(node.nodeId, '0.0', 'Append single node before : correct id'); + } + }); + tree = $tree.treeview(true) + parent = tree.findNodes('Parent 1', 'text'); + tree.addNodeBefore(singleNode, parent); - var enabledNodes = tree.getEnabled(); - ok((enabledNodes instanceof Array), 'Result is an array'); - equal(enabledNodes.length, 8, 'Correct number of nodes returned'); + // Append multiple nodes before + $tree = init({ + data: data, + onNodeRendered: function (events, node) { + if (node.text === multiNodes[0].text) { + equal(node.level, 1, 'Append multiple nodes before 1 : correct level'); + equal(node.nodeId, '0.0', 'Append multiple nodes before 1 : correct id'); + } else if (node.text === multiNodes[1].text) { + equal(node.level, 1, 'Append multiple nodes before 2 : correct level'); + equal(node.nodeId, '0.1', 'Append multiple nodes before 2 : correct id'); + start(); + } + } + }); + tree = $tree.treeview(true) + parent = tree.findNodes('Parent 1', 'text'); + tree.addNodeBefore(multiNodes, parent); }); test('disableAll / enableAll', function () { From 6049c3191b858d0da5b393a41f7387af83a6e656 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sun, 5 Jun 2016 21:11:38 +0100 Subject: [PATCH 45/52] Implemented removeNode, updateNode --- src/js/bootstrap-treeview.js | 110 +++++++++++++++++++++++++++++++---- tests/tests.js | 50 ++++++++++++++-- 2 files changed, 144 insertions(+), 16 deletions(-) diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index e0e78860b..b5cc124b6 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -113,8 +113,9 @@ init: $.proxy(this._init, this), remove: $.proxy(this._remove, this), - // Get methods + // Query methods findNodes: $.proxy(this.findNodes, this), + getNodes: $.proxy(this.getNodes, this), // todo document + test getParents: $.proxy(this.getParents, this), getSiblings: $.proxy(this.getSiblings, this), getSelected: $.proxy(this.getSelected, this), @@ -130,6 +131,8 @@ addNode: $.proxy(this.addNode, this), addNodeAfter: $.proxy(this.addNodeAfter, this), addNodeBefore: $.proxy(this.addNodeBefore, this), + removeNode: $.proxy(this.removeNode, this), + updateNode: $.proxy(this.updateNode, this), // Select methods selectNode: $.proxy(this.selectNode, this), @@ -166,8 +169,6 @@ Tree.prototype._init = function (options) { this._tree = []; - this._nodes = {}; - this._orderedNodes = []; this._initialized = false; this._options = $.extend({}, _default.settings, options); @@ -343,6 +344,7 @@ index nodes in a flattened ordered structure */ Tree.prototype._setInitialStates = function (node, level) { + this._nodes = {}; return $.when.apply(this, this._setInitialState(node, level)) .done($.proxy(function () { this._orderedNodes = this._sortNodes(); @@ -829,6 +831,7 @@ // ensures the template is inserted at the correct position Tree.prototype._newNodeEl = function (node, previousNode) { var $el = $(this._template.node); + if (previousNode) { // typical usage, as nodes are rendered in // sort order we add after the previous element @@ -840,12 +843,26 @@ // to cater for root inserts i.e. nodeId 0.0 this.$wrapper.prepend($el); } + return $el; }; + // Recursively remove node elements from DOM + Tree.prototype._removeNodeEl = function (node) { + if (!node) return; + + if (node.nodes) { + $.each(node.nodes, $.proxy(function (index, node) { + this._removeNodeEl(node); + }, this)); + } + node.$el.remove(); + }; + // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; + $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { childNode.level = node.level + 1; this._renderNode(childNode, node.$el); @@ -953,6 +970,15 @@ return this._findNodes(pattern, field); }; + + /** + Returns an ordered aarray of node objects. + @return {Array} nodes - An array of all nodes + */ + Tree.prototype.getNodes = function () { + return this._orderedNodes; + }; + /** Returns parent nodes for given nodes, if valid otherwise returns undefined. @param {Array} nodes - An array of nodes @@ -1094,15 +1120,13 @@ }, this)); // initialize new state and render changes - if (parentNode) { - this._setInitialStates(parentNode, parentNode.level); - if (!parentNode.state.expanded) { - this._setExpanded(parentNode, true, options); - } - } else { - this._setInitialStates({nodes: targetNodes}, 0); - } - this._render(); + this._setInitialStates({nodes: this._tree}, 0) + .done($.proxy(function () { + if (parentNode && !parentNode.state.expanded) { + this._setExpanded(parentNode, true, options); + } + this._render(); + }, this)); } /** @@ -1141,6 +1165,68 @@ this.addNode(nodes, this.getParents(node)[0], node.index, options); } + /** + Removes given nodes from the tree. + @param {Array} nodes - An array of nodes to remove + @param {optional Object} options + */ + Tree.prototype.removeNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + + var targetNodes, parentNode; + $.each(nodes, $.proxy(function (index, node) { + + // remove nodes from tree + parentNode = this._nodes[node.parentId]; + if (parentNode) { + targetNodes = parentNode.nodes; + } else { + targetNodes = this._tree; + } + targetNodes.splice(node.index, 1); + + // remove node from DOM + this._removeNodeEl(node); + }, this)); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done(this._render.bind(this)); + }; + + /** + Updates / replaces a given tree node + @param {Object} node - A single node to be replaced + @param {Object} newNode - THe replacement node + @param {optional Object} options + */ + Tree.prototype.updateNode = function (node, newNode, options) { + if (node instanceof Array) { + node = node[0]; + } + options = $.extend({}, _default.options, options); + + // insert new node + var targetNodes; + var parentNode = this._nodes[node.parentId]; + if (parentNode) { + targetNodes = parentNode.nodes; + } else { + targetNodes = this._tree; + } + targetNodes.splice(node.index, 1, newNode); + + // remove old node from DOM + this._removeNodeEl(node); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done(this._render.bind(this)); + }; + /** Selects given tree nodes diff --git a/tests/tests.js b/tests/tests.js index bee288968..26e19179d 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -827,7 +827,7 @@ equal(node.nodeId, '0.1', 'Append single node after : correct id'); } }); - tree = $tree.treeview(true) + tree = $tree.treeview(true); parent = tree.findNodes('Parent 1', 'text'); tree.addNodeAfter(singleNode, parent); @@ -845,7 +845,7 @@ } } }); - tree = $tree.treeview(true) + tree = $tree.treeview(true); parent = tree.findNodes('Parent 1', 'text'); tree.addNodeAfter(multiNodes, parent); }); @@ -864,7 +864,7 @@ equal(node.nodeId, '0.0', 'Append single node before : correct id'); } }); - tree = $tree.treeview(true) + tree = $tree.treeview(true); parent = tree.findNodes('Parent 1', 'text'); tree.addNodeBefore(singleNode, parent); @@ -882,11 +882,53 @@ } } }); - tree = $tree.treeview(true) + tree = $tree.treeview(true); parent = tree.findNodes('Parent 1', 'text'); tree.addNodeBefore(multiNodes, parent); }); + asyncTest('removeNode', function (assert) { + var $tree, tree, node, first = true; + + // Remove single node + $tree = init({ + data: data, + onRendered: function (events, nodes) { + if (first) { + first = false; + return; + } + equal(tree.getNodes().length, 4, 'Remove single node - correct number of nodes remain'); + start(); + } + }); + tree = $tree.treeview(true); + node = tree.findNodes('Parent 1', 'text'); + tree.removeNode(node); + }); + + asyncTest('updateNode', function (assert) { + var $tree, tree, parent, first = true; + + // Remove single node + $tree = init({ + data: data, + onRendered: function (events, nodes) { + if (first) { + first = false; + return; + } + equal(tree.getNodes().length, 5, 'Update single node - correct number of nodes'); + // equal($($tree.selector + ' ul li').length, 5, 'Update single node - correct number of elements'); + equal(tree.getNodes()[0].text, singleNode.text, 'Update single node - correct text'); + start(); + } + }); + tree = $tree.treeview(true); + parent = tree.findNodes('Parent 1', 'text'); + tree.updateNode(parent, singleNode); + }); + test('disableAll / enableAll', function () { var $tree = init({ data: data, levels: 1 }); var tree = $tree.treeview(true); From 8d0510667ffebb05fba12d4e0dad8799a50846a0 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 18 Jun 2016 12:07:50 +0100 Subject: [PATCH 46/52] Ensure all API methods accept nodes as either a single node or an array of nodes. --- src/js/bootstrap-treeview.js | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index b5cc124b6..a2292697a 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -1005,6 +1005,10 @@ @returns {Array} nodes - An array of sibling nodes */ Tree.prototype.getSiblings = function (nodes) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + var siblingNodes = []; $.each(nodes, $.proxy(function (index, node) { var parent = this.getParents([node]); @@ -1139,9 +1143,11 @@ if (!(nodes instanceof Array)) { nodes = [nodes]; } + if (node instanceof Array) { node = node[0]; } + options = $.extend({}, _default.options, options); this.addNode(nodes, this.getParents(node)[0], (node.index + 1), options); @@ -1157,9 +1163,11 @@ if (!(nodes instanceof Array)) { nodes = [nodes]; } + if (node instanceof Array) { node = node[0]; } + options = $.extend({}, _default.options, options); this.addNode(nodes, this.getParents(node)[0], node.index, options); @@ -1174,6 +1182,7 @@ if (!(nodes instanceof Array)) { nodes = [nodes]; } + options = $.extend({}, _default.options, options); var targetNodes, parentNode; @@ -1207,6 +1216,7 @@ if (node instanceof Array) { node = node[0]; } + options = $.extend({}, _default.options, options); // insert new node @@ -1234,7 +1244,12 @@ @param {optional Object} options */ Tree.prototype.selectNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, true, options); }, this)); @@ -1246,7 +1261,12 @@ @param {optional Object} options */ Tree.prototype.unselectNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, false, options); }, this)); @@ -1258,7 +1278,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeSelected = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleSelected(node, options); }, this)); @@ -1282,6 +1307,7 @@ */ Tree.prototype.collapseNode = function (nodes, options) { options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, false, options); }, this)); @@ -1303,7 +1329,12 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, true, options); if (node.nodes) { @@ -1313,6 +1344,12 @@ }; Tree.prototype._expandLevels = function (nodes, level, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, (level > 0) ? true : false, options); if (node.nodes) { @@ -1327,7 +1364,12 @@ @param {optional Object} options */ Tree.prototype.revealNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { var parentNode = node; var tmpNode; @@ -1344,7 +1386,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeExpanded = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleExpanded(node, options); }, this)); @@ -1357,6 +1404,7 @@ */ Tree.prototype.checkAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.checked'); $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); @@ -1369,7 +1417,12 @@ @param {optional Object} options */ Tree.prototype.checkNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); @@ -1381,6 +1434,7 @@ */ Tree.prototype.uncheckAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.checked'); $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); @@ -1393,7 +1447,12 @@ @param {optional Object} options */ Tree.prototype.uncheckNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); @@ -1405,7 +1464,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeChecked = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleChecked(node, options); }, this)); @@ -1418,6 +1482,7 @@ */ Tree.prototype.disableAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.disabled'); $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); @@ -1430,7 +1495,12 @@ @param {optional Object} options */ Tree.prototype.disableNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); @@ -1442,6 +1512,7 @@ */ Tree.prototype.enableAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.disabled'); $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); @@ -1454,7 +1525,12 @@ @param {optional Object} options */ Tree.prototype.enableNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); @@ -1466,7 +1542,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeDisabled = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, !node.state.disabled, options); }, this)); From 16a17460c3348f6963777e4fa7fbcbb824b84346 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 18 Jun 2016 12:15:52 +0100 Subject: [PATCH 47/52] Documented additional method; getNodes --- README.md | 8 + dist/bootstrap-treeview.min.js | 2 +- public/js/bootstrap-treeview.js | 402 ++++++++++++++++++++++++++------ tests/lib/bootstrap-treeview.js | 402 ++++++++++++++++++++++++++------ tests/tests.js | 7 + 5 files changed, 684 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 9eb30fa7c..f7d6c5b84 100644 --- a/README.md +++ b/README.md @@ -612,6 +612,14 @@ Returns an array of expanded nodes e.g. state.expanded = true. $('#tree').treeview('getExpanded'); ``` +#### getNodes() + +Returns an array of all initialized nodes. + +```javascript +$('#tree').treeview('getNodes', nodes); +``` + #### getParents(nodes) Returns parent nodes for given nodes, if valid otherwise returns undefined. diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index e367433ea..bb438f403 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._nodes=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(b){return a.when.apply(this,this._setInitialStates({nodes:b},0)).done(a.proxy(function(){this._triggerEvent("initialized",this._nodes,f.options)},this))},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b,f=this;return a.each(b.nodes,function(b,g){var h=new a.Deferred;d.push(h.promise()),g.index=b,g.nodeId=f._nodes.length,g.parentId=e.nodeId,g.hasOwnProperty("selectable")||(g.selectable=!0),g.state=g.state||{},g.state.hasOwnProperty("checked")||(g.state.checked=!1),g.state.hasOwnProperty("disabled")||(g.state.disabled=!1),g.state.hasOwnProperty("expanded")||(!g.state.disabled&&c0?g.state.expanded=!0:g.state.expanded=!1),c>f._options.levels?g.state.visible=!1:g.state.visible=!0,g.state.hasOwnProperty("selected")||(g.state.selected=!1),f._nodes.push(g),g.nodes&&(g.nodes.length>0?f._setInitialStates(g,c,d):delete g.nodes),h.resolve()}),d}},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0),this._tree&&(a.each(this._tree,a.proxy(function(a,b){b.level=1,this._renderNode(b)},this)),this._triggerEvent("rendered",this._nodes,f.options))},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():(b.$el=this._newNodeEl(c),b.$el.addClass("node-"+this._elementId).attr("data-nodeid",b.nodeId));for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._nodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeid="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                              ',node:'
                                                                                                                            • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getParents=function(b){var c=[];return a.each(b,a.proxy(function(a,b){c.push(this._nodes[b.parentId])},this)),c},g.prototype.getSiblings=function(b){var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.selectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._nodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getNodes:a.proxy(this.getNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),addNode:a.proxy(this.addNode,this),addNodeAfter:a.proxy(this.addNodeAfter,this),addNodeBefore:a.proxy(this.addNodeBefore,this),removeNode:a.proxy(this.removeNode,this),updateNode:a.proxy(this.updateNode,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(a){return this._setInitialStates({nodes:a},0)},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c){return this._nodes={},a.when.apply(this,this._setInitialState(b,c)).done(a.proxy(function(){this._orderedNodes=this._sortNodes(),this._triggerEvent("initialized",this._orderedNodes,f.options)},this))},g.prototype._setInitialState=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b;return a.each(b.nodes,a.proxy(function(b,f){var g=new a.Deferred;d.push(g.promise()),f.level=c,f.index=b,f.nodeId=e&&e.nodeId?e.nodeId+"."+f.index:c-1+"."+f.index,f.parentId=e.nodeId,f.hasOwnProperty("selectable")||(f.selectable=!0),f.state=f.state||{},f.state.hasOwnProperty("checked")||(f.state.checked=!1),f.state.hasOwnProperty("disabled")||(f.state.disabled=!1),f.state.hasOwnProperty("expanded")||(!f.state.disabled&&c0?f.state.expanded=!0:f.state.expanded=!1),f.state.hasOwnProperty("selected")||(f.state.selected=!1),e&&e.state&&e.state.expanded||c<=this._options.levels?f.state.visible=!0:f.state.visible=!1,f.nodes&&(f.nodes.length>0?this._setInitialState(f,c,d):delete f.nodes),this._nodes[f.nodeId]=f,g.resolve()},this)),d}},g.prototype._sortNodes=function(){return a.map(Object.keys(this._nodes).sort(),a.proxy(function(a,b){return this._nodes[a]},this))},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeId"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0);var b;a.each(this._orderedNodes,a.proxy(function(a,c){this._renderNode(c,b),b=c},this)),this._triggerEvent("rendered",this._orderedNodes,f.options)},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():b.$el=this._newNodeEl(b,c).addClass("node-"+this._elementId),b.$el.attr("data-nodeId",b.nodeId);for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._orderedNodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeId="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                                ',node:'
                                                                                                                              • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getNodes=function(){return this._orderedNodes},g.prototype.getParents=function(b){b instanceof Array||(b=[b]);var c=[];return a.each(b,a.proxy(function(a,b){var d=b.parentId?this._nodes[b.parentId]:!1;d&&c.push(d)},this)),c},g.prototype.getSiblings=function(b){b instanceof Array||(b=[b]);var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.addNode=function(b,c,d,e){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),e=a.extend({},f.options,e);var g;g=c&&c.nodes?c.nodes:c?c.nodes=[]:this._tree,a.each(b,a.proxy(function(a,b){var c="number"==typeof d?d+a:g.length+1;g.splice(c,0,b)},this)),this._setInitialStates({nodes:this._tree},0).done(a.proxy(function(){c&&!c.state.expanded&&this._setExpanded(c,!0,e),this._render()},this))},g.prototype.addNodeAfter=function(b,c,d){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),d=a.extend({},f.options,d),this.addNode(b,this.getParents(c)[0],c.index+1,d)},g.prototype.addNodeBefore=function(b,c,d){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),d=a.extend({},f.options,d),this.addNode(b,this.getParents(c)[0],c.index,d)},g.prototype.removeNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c);var d,e;a.each(b,a.proxy(function(a,b){e=this._nodes[b.parentId],d=e?e.nodes:this._tree,d.splice(b.index,1),this._removeNodeEl(b)},this)),this._setInitialStates({nodes:this._tree},0).done(this._render.bind(this))},g.prototype.updateNode=function(b,c,d){b instanceof Array&&(b=b[0]),d=a.extend({},f.options,d);var e,g=this._nodes[b.parentId];e=g?g.nodes:this._tree,e.splice(b.index,1,c),this._removeNodeEl(b),this._setInitialStates({nodes:this._tree},0).done(this._render.bind(this))},g.prototype.selectNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){b instanceof Array||(b=[b]),d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._orderedNodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index 25d1ff355..a2292697a 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -113,8 +113,9 @@ init: $.proxy(this._init, this), remove: $.proxy(this._remove, this), - // Get methods + // Query methods findNodes: $.proxy(this.findNodes, this), + getNodes: $.proxy(this.getNodes, this), // todo document + test getParents: $.proxy(this.getParents, this), getSiblings: $.proxy(this.getSiblings, this), getSelected: $.proxy(this.getSelected, this), @@ -126,6 +127,13 @@ getDisabled: $.proxy(this.getDisabled, this), getEnabled: $.proxy(this.getEnabled, this), + // Tree manipulation methods + addNode: $.proxy(this.addNode, this), + addNodeAfter: $.proxy(this.addNodeAfter, this), + addNodeBefore: $.proxy(this.addNodeBefore, this), + removeNode: $.proxy(this.removeNode, this), + updateNode: $.proxy(this.updateNode, this), + // Select methods selectNode: $.proxy(this.selectNode, this), unselectNode: $.proxy(this.unselectNode, this), @@ -139,7 +147,7 @@ toggleNodeExpanded: $.proxy(this.toggleNodeExpanded, this), revealNode: $.proxy(this.revealNode, this), - // Expand / collapse methods + // Check / uncheck methods checkAll: $.proxy(this.checkAll, this), checkNode: $.proxy(this.checkNode, this), uncheckAll: $.proxy(this.uncheckAll, this), @@ -161,7 +169,6 @@ Tree.prototype._init = function (options) { this._tree = []; - this._nodes = []; this._initialized = false; this._options = $.extend({}, _default.settings, options); @@ -180,10 +187,7 @@ }, this)) .then($.proxy(function (treeData) { // initialize data - return $.when.apply(this, this._setInitialStates({ nodes: treeData }, 0)) - .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes, _default.options); - }, this)); + return this._setInitialStates({ nodes: treeData }, 0); }, this)) .then($.proxy(function () { // render to DOM @@ -337,25 +341,38 @@ Recurse the tree structure and ensure all nodes have valid initial states. User defined states will be preserved. For performance we also take this opportunity to - index nodes in a flattened structure + index nodes in a flattened ordered structure */ - Tree.prototype._setInitialStates = function (node, level, ready) { + Tree.prototype._setInitialStates = function (node, level) { + this._nodes = {}; + return $.when.apply(this, this._setInitialState(node, level)) + .done($.proxy(function () { + this._orderedNodes = this._sortNodes(); + this._triggerEvent('initialized', this._orderedNodes, _default.options); + return; + }, this)); + }; + Tree.prototype._setInitialState = function (node, level, done) { if (!node.nodes) return; level += 1; - ready = ready || []; + done = done || []; var parent = node; - var _this = this; - $.each(node.nodes, function checkStates(index, node) { + $.each(node.nodes, $.proxy(function (index, node) { var deferred = new $.Deferred(); - ready.push(deferred.promise()); + done.push(deferred.promise()); + + // level : hierarchical tree level, starts at 1 + node.level = level; // index : relative to siblings node.index = index; - // nodeId : unique, incremental identifier - node.nodeId = _this._nodes.length; + // nodeId : unique, hierarchical identifier + node.nodeId = (parent && parent.nodeId) ? + parent.nodeId + '.' + node.index : + (level - 1) + '.' + node.index; // parentId : transversing up the tree node.parentId = parent.nodeId; @@ -381,7 +398,7 @@ // set expanded state; if not provided based on levels if (!node.state.hasOwnProperty('expanded')) { if (!node.state.disabled && - (level < _this._options.levels) && + (level < this._options.levels) && (node.nodes && node.nodes.length > 0)) { node.state.expanded = true; } @@ -390,36 +407,44 @@ } } - // set visible state; based purely on levels - if (level > _this._options.levels) { - node.state.visible = false; - } - else { - node.state.visible = true; - } - // set selected state; unless set always false if (!node.state.hasOwnProperty('selected')) { node.state.selected = false; } - // index nodes in a flattened structure for use later - _this._nodes.push(node); + // set visible state; based parent state plus levels + if ((parent && parent.state && parent.state.expanded) || + (level <= this._options.levels)) { + node.state.visible = true; + } + else { + node.state.visible = false; + } - // recurse child nodes and transverse the tree + // recurse child nodes and transverse the tree, depth-first if (node.nodes) { if (node.nodes.length > 0) { - _this._setInitialStates(node, level, ready); + this._setInitialState(node, level, done); } else { delete node.nodes; } } + // add / update indexed collection + this._nodes[node.nodeId] = node; + + // mark task as complete deferred.resolve(); - }); + }, this)); + + return done; + }; - return ready; + Tree.prototype._sortNodes = function () { + return $.map(Object.keys(this._nodes).sort(), $.proxy(function (value, index) { + return this._nodes[value]; + }, this)); }; Tree.prototype._clickHandler = function (event) { @@ -447,10 +472,8 @@ // Looks up the DOM for the closest parent list item to retrieve the // data attribute nodeid, which is used to lookup the node in the flattened structure. Tree.prototype.targetNode = function (target) { - - var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); + var nodeId = target.closest('li.list-group-item').attr('data-nodeId'); var node = this._nodes[nodeId]; - if (!node) { console.log('Error: node does not exist'); } @@ -728,33 +751,29 @@ this._initialized = true; } - if (!this._tree) return; - - $.each(this._tree, $.proxy(function addRootNodes(id, node) { - node.level = 1; - this._renderNode(node); + var previousNode; + $.each(this._orderedNodes, $.proxy(function (id, node) { + this._renderNode(node, previousNode); + previousNode = node; }, this)); - this._triggerEvent('rendered', this._nodes, _default.options); + this._triggerEvent('rendered', this._orderedNodes, _default.options); }; - Tree.prototype._renderNode = function (node, pEl) { + Tree.prototype._renderNode = function (node, previousNode) { if (!node) return; if (!node.$el) { - - // New node, needs a new element - node.$el = this._newNodeEl(pEl); - - // One time setup - node.$el - .addClass('node-' + this._elementId) - .attr('data-nodeid', node.nodeId); + node.$el = this._newNodeEl(node, previousNode) + .addClass('node-' + this._elementId); } else { node.$el.empty(); } + // Set / update nodeid; it can change as a result of addNode etc. + node.$el.attr('data-nodeId', node.nodeId); + // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { node.$el.append(this._template.indent); @@ -804,42 +823,49 @@ this._setDisabled(node, node.state.disabled); this._setVisible(node, node.state.visible); - // If children exist, recursively add - if (node.nodes) { - $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { - childNode.level = node.level + 1; - this._renderNode(childNode, node.$el); - }, this)); - } - // Trigger nodeRendered event this._triggerEvent('nodeRendered', node, _default.options); }; // Creates a new node element from template and // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (pEl) { + Tree.prototype._newNodeEl = function (node, previousNode) { var $el = $(this._template.node); - if (pEl) { + if (previousNode) { + // typical usage, as nodes are rendered in + // sort order we add after the previous element this.$wrapper.children() - .eq(pEl.index()).after($el); - } - else { - this.$wrapper.append($el); + .eq(previousNode.$el.index()) + .after($el); + } else { + // we use prepend instead of append, + // to cater for root inserts i.e. nodeId 0.0 + this.$wrapper.prepend($el); } return $el; }; + // Recursively remove node elements from DOM + Tree.prototype._removeNodeEl = function (node) { + if (!node) return; + + if (node.nodes) { + $.each(node.nodes, $.proxy(function (index, node) { + this._removeNodeEl(node); + }, this)); + } + node.$el.remove(); + }; + // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; - var $pEl = node.$el; $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { childNode.level = node.level + 1; - this._renderNode(childNode, $pEl); + this._renderNode(childNode, node.$el); }, this)); }; @@ -908,7 +934,7 @@ } // Node level style overrides - $.each(this._nodes, $.proxy(function (index, node) { + $.each(this._orderedNodes, $.proxy(function (index, node) { if (node.color || node.backColor) { var innerStyle = ''; if (node.color) { @@ -917,7 +943,7 @@ if (node.backColor) { innerStyle += 'background-color:' + node.backColor + ';'; } - style += '.node-' + this._elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + style += '.node-' + this._elementId + '[data-nodeId="' + node.nodeId + '"]{' + innerStyle + '}'; } }, this)); @@ -944,15 +970,31 @@ return this._findNodes(pattern, field); }; + + /** + Returns an ordered aarray of node objects. + @return {Array} nodes - An array of all nodes + */ + Tree.prototype.getNodes = function () { + return this._orderedNodes; + }; + /** Returns parent nodes for given nodes, if valid otherwise returns undefined. @param {Array} nodes - An array of nodes @returns {Array} nodes - An array of parent nodes */ Tree.prototype.getParents = function (nodes) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + var parentNodes = []; $.each(nodes, $.proxy(function (index, node) { - parentNodes.push(this._nodes[node.parentId]); + var parentNode = node.parentId ? this._nodes[node.parentId] : false; + if (parentNode) { + parentNodes.push(parentNode); + } }, this)); return parentNodes; }; @@ -963,6 +1005,10 @@ @returns {Array} nodes - An array of sibling nodes */ Tree.prototype.getSiblings = function (nodes) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + var siblingNodes = []; $.each(nodes, $.proxy(function (index, node) { var parent = this.getParents([node]); @@ -1043,13 +1089,167 @@ }; + /** + Add nodes to the tree. + @param {Array} nodes - An array of nodes to add + @param {optional Object} parentNode - The node to which nodes will be added as children + @param {optional number} index - Zero based insert index + @param {optional Object} options + */ + Tree.prototype.addNode = function (nodes, parentNode, index, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (parentNode instanceof Array) { + parentNode = parentNode[0]; + } + + options = $.extend({}, _default.options, options); + + // identify target nodes; either the tree's root or a parent's child nodes + var targetNodes; + if (parentNode && parentNode.nodes) { + targetNodes = parentNode.nodes; + } else if (parentNode) { + targetNodes = parentNode.nodes = []; + } else { + targetNodes = this._tree; + } + + // inserting nodes at specified positions + $.each(nodes, $.proxy(function (i, node) { + var insertIndex = (typeof(index) === 'number') ? (index + i) : (targetNodes.length + 1); + targetNodes.splice(insertIndex, 0, node); + }, this)); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done($.proxy(function () { + if (parentNode && !parentNode.state.expanded) { + this._setExpanded(parentNode, true, options); + } + this._render(); + }, this)); + } + + /** + Add nodes to the tree after given node. + @param {Array} nodes - An array of nodes to add + @param {Object} node - The node to which nodes will be added after + @param {optional Object} options + */ + Tree.prototype.addNodeAfter = function (nodes, node, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (node instanceof Array) { + node = node[0]; + } + + options = $.extend({}, _default.options, options); + + this.addNode(nodes, this.getParents(node)[0], (node.index + 1), options); + } + + /** + Add nodes to the tree before given node. + @param {Array} nodes - An array of nodes to add + @param {Object} node - The node to which nodes will be added before + @param {optional Object} options + */ + Tree.prototype.addNodeBefore = function (nodes, node, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (node instanceof Array) { + node = node[0]; + } + + options = $.extend({}, _default.options, options); + + this.addNode(nodes, this.getParents(node)[0], node.index, options); + } + + /** + Removes given nodes from the tree. + @param {Array} nodes - An array of nodes to remove + @param {optional Object} options + */ + Tree.prototype.removeNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + options = $.extend({}, _default.options, options); + + var targetNodes, parentNode; + $.each(nodes, $.proxy(function (index, node) { + + // remove nodes from tree + parentNode = this._nodes[node.parentId]; + if (parentNode) { + targetNodes = parentNode.nodes; + } else { + targetNodes = this._tree; + } + targetNodes.splice(node.index, 1); + + // remove node from DOM + this._removeNodeEl(node); + }, this)); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done(this._render.bind(this)); + }; + + /** + Updates / replaces a given tree node + @param {Object} node - A single node to be replaced + @param {Object} newNode - THe replacement node + @param {optional Object} options + */ + Tree.prototype.updateNode = function (node, newNode, options) { + if (node instanceof Array) { + node = node[0]; + } + + options = $.extend({}, _default.options, options); + + // insert new node + var targetNodes; + var parentNode = this._nodes[node.parentId]; + if (parentNode) { + targetNodes = parentNode.nodes; + } else { + targetNodes = this._tree; + } + targetNodes.splice(node.index, 1, newNode); + + // remove old node from DOM + this._removeNodeEl(node); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done(this._render.bind(this)); + }; + + /** Selects given tree nodes @param {Array} nodes - An array of nodes @param {optional Object} options */ Tree.prototype.selectNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, true, options); }, this)); @@ -1061,7 +1261,12 @@ @param {optional Object} options */ Tree.prototype.unselectNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, false, options); }, this)); @@ -1073,7 +1278,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeSelected = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleSelected(node, options); }, this)); @@ -1097,6 +1307,7 @@ */ Tree.prototype.collapseNode = function (nodes, options) { options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, false, options); }, this)); @@ -1118,7 +1329,12 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, true, options); if (node.nodes) { @@ -1128,6 +1344,12 @@ }; Tree.prototype._expandLevels = function (nodes, level, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, (level > 0) ? true : false, options); if (node.nodes) { @@ -1142,7 +1364,12 @@ @param {optional Object} options */ Tree.prototype.revealNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { var parentNode = node; var tmpNode; @@ -1159,7 +1386,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeExpanded = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleExpanded(node, options); }, this)); @@ -1172,6 +1404,7 @@ */ Tree.prototype.checkAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.checked'); $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); @@ -1184,7 +1417,12 @@ @param {optional Object} options */ Tree.prototype.checkNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); @@ -1196,6 +1434,7 @@ */ Tree.prototype.uncheckAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.checked'); $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); @@ -1208,7 +1447,12 @@ @param {optional Object} options */ Tree.prototype.uncheckNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); @@ -1220,7 +1464,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeChecked = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleChecked(node, options); }, this)); @@ -1233,6 +1482,7 @@ */ Tree.prototype.disableAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.disabled'); $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); @@ -1245,7 +1495,12 @@ @param {optional Object} options */ Tree.prototype.disableNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); @@ -1257,6 +1512,7 @@ */ Tree.prototype.enableAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.disabled'); $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); @@ -1269,7 +1525,12 @@ @param {optional Object} options */ Tree.prototype.enableNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); @@ -1281,7 +1542,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeDisabled = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, !node.state.disabled, options); }, this)); @@ -1371,7 +1637,7 @@ Tree.prototype._findNodes = function (pattern, attribute, modifier) { attribute = attribute || 'text'; modifier = modifier || 'g'; - return $.grep(this._nodes, $.proxy(function (node) { + return $.grep(this._orderedNodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index 25d1ff355..a2292697a 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -113,8 +113,9 @@ init: $.proxy(this._init, this), remove: $.proxy(this._remove, this), - // Get methods + // Query methods findNodes: $.proxy(this.findNodes, this), + getNodes: $.proxy(this.getNodes, this), // todo document + test getParents: $.proxy(this.getParents, this), getSiblings: $.proxy(this.getSiblings, this), getSelected: $.proxy(this.getSelected, this), @@ -126,6 +127,13 @@ getDisabled: $.proxy(this.getDisabled, this), getEnabled: $.proxy(this.getEnabled, this), + // Tree manipulation methods + addNode: $.proxy(this.addNode, this), + addNodeAfter: $.proxy(this.addNodeAfter, this), + addNodeBefore: $.proxy(this.addNodeBefore, this), + removeNode: $.proxy(this.removeNode, this), + updateNode: $.proxy(this.updateNode, this), + // Select methods selectNode: $.proxy(this.selectNode, this), unselectNode: $.proxy(this.unselectNode, this), @@ -139,7 +147,7 @@ toggleNodeExpanded: $.proxy(this.toggleNodeExpanded, this), revealNode: $.proxy(this.revealNode, this), - // Expand / collapse methods + // Check / uncheck methods checkAll: $.proxy(this.checkAll, this), checkNode: $.proxy(this.checkNode, this), uncheckAll: $.proxy(this.uncheckAll, this), @@ -161,7 +169,6 @@ Tree.prototype._init = function (options) { this._tree = []; - this._nodes = []; this._initialized = false; this._options = $.extend({}, _default.settings, options); @@ -180,10 +187,7 @@ }, this)) .then($.proxy(function (treeData) { // initialize data - return $.when.apply(this, this._setInitialStates({ nodes: treeData }, 0)) - .done($.proxy(function () { - this._triggerEvent('initialized', this._nodes, _default.options); - }, this)); + return this._setInitialStates({ nodes: treeData }, 0); }, this)) .then($.proxy(function () { // render to DOM @@ -337,25 +341,38 @@ Recurse the tree structure and ensure all nodes have valid initial states. User defined states will be preserved. For performance we also take this opportunity to - index nodes in a flattened structure + index nodes in a flattened ordered structure */ - Tree.prototype._setInitialStates = function (node, level, ready) { + Tree.prototype._setInitialStates = function (node, level) { + this._nodes = {}; + return $.when.apply(this, this._setInitialState(node, level)) + .done($.proxy(function () { + this._orderedNodes = this._sortNodes(); + this._triggerEvent('initialized', this._orderedNodes, _default.options); + return; + }, this)); + }; + Tree.prototype._setInitialState = function (node, level, done) { if (!node.nodes) return; level += 1; - ready = ready || []; + done = done || []; var parent = node; - var _this = this; - $.each(node.nodes, function checkStates(index, node) { + $.each(node.nodes, $.proxy(function (index, node) { var deferred = new $.Deferred(); - ready.push(deferred.promise()); + done.push(deferred.promise()); + + // level : hierarchical tree level, starts at 1 + node.level = level; // index : relative to siblings node.index = index; - // nodeId : unique, incremental identifier - node.nodeId = _this._nodes.length; + // nodeId : unique, hierarchical identifier + node.nodeId = (parent && parent.nodeId) ? + parent.nodeId + '.' + node.index : + (level - 1) + '.' + node.index; // parentId : transversing up the tree node.parentId = parent.nodeId; @@ -381,7 +398,7 @@ // set expanded state; if not provided based on levels if (!node.state.hasOwnProperty('expanded')) { if (!node.state.disabled && - (level < _this._options.levels) && + (level < this._options.levels) && (node.nodes && node.nodes.length > 0)) { node.state.expanded = true; } @@ -390,36 +407,44 @@ } } - // set visible state; based purely on levels - if (level > _this._options.levels) { - node.state.visible = false; - } - else { - node.state.visible = true; - } - // set selected state; unless set always false if (!node.state.hasOwnProperty('selected')) { node.state.selected = false; } - // index nodes in a flattened structure for use later - _this._nodes.push(node); + // set visible state; based parent state plus levels + if ((parent && parent.state && parent.state.expanded) || + (level <= this._options.levels)) { + node.state.visible = true; + } + else { + node.state.visible = false; + } - // recurse child nodes and transverse the tree + // recurse child nodes and transverse the tree, depth-first if (node.nodes) { if (node.nodes.length > 0) { - _this._setInitialStates(node, level, ready); + this._setInitialState(node, level, done); } else { delete node.nodes; } } + // add / update indexed collection + this._nodes[node.nodeId] = node; + + // mark task as complete deferred.resolve(); - }); + }, this)); + + return done; + }; - return ready; + Tree.prototype._sortNodes = function () { + return $.map(Object.keys(this._nodes).sort(), $.proxy(function (value, index) { + return this._nodes[value]; + }, this)); }; Tree.prototype._clickHandler = function (event) { @@ -447,10 +472,8 @@ // Looks up the DOM for the closest parent list item to retrieve the // data attribute nodeid, which is used to lookup the node in the flattened structure. Tree.prototype.targetNode = function (target) { - - var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); + var nodeId = target.closest('li.list-group-item').attr('data-nodeId'); var node = this._nodes[nodeId]; - if (!node) { console.log('Error: node does not exist'); } @@ -728,33 +751,29 @@ this._initialized = true; } - if (!this._tree) return; - - $.each(this._tree, $.proxy(function addRootNodes(id, node) { - node.level = 1; - this._renderNode(node); + var previousNode; + $.each(this._orderedNodes, $.proxy(function (id, node) { + this._renderNode(node, previousNode); + previousNode = node; }, this)); - this._triggerEvent('rendered', this._nodes, _default.options); + this._triggerEvent('rendered', this._orderedNodes, _default.options); }; - Tree.prototype._renderNode = function (node, pEl) { + Tree.prototype._renderNode = function (node, previousNode) { if (!node) return; if (!node.$el) { - - // New node, needs a new element - node.$el = this._newNodeEl(pEl); - - // One time setup - node.$el - .addClass('node-' + this._elementId) - .attr('data-nodeid', node.nodeId); + node.$el = this._newNodeEl(node, previousNode) + .addClass('node-' + this._elementId); } else { node.$el.empty(); } + // Set / update nodeid; it can change as a result of addNode etc. + node.$el.attr('data-nodeId', node.nodeId); + // Add indent/spacer to mimic tree structure for (var i = 0; i < (node.level - 1); i++) { node.$el.append(this._template.indent); @@ -804,42 +823,49 @@ this._setDisabled(node, node.state.disabled); this._setVisible(node, node.state.visible); - // If children exist, recursively add - if (node.nodes) { - $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { - childNode.level = node.level + 1; - this._renderNode(childNode, node.$el); - }, this)); - } - // Trigger nodeRendered event this._triggerEvent('nodeRendered', node, _default.options); }; // Creates a new node element from template and // ensures the template is inserted at the correct position - Tree.prototype._newNodeEl = function (pEl) { + Tree.prototype._newNodeEl = function (node, previousNode) { var $el = $(this._template.node); - if (pEl) { + if (previousNode) { + // typical usage, as nodes are rendered in + // sort order we add after the previous element this.$wrapper.children() - .eq(pEl.index()).after($el); - } - else { - this.$wrapper.append($el); + .eq(previousNode.$el.index()) + .after($el); + } else { + // we use prepend instead of append, + // to cater for root inserts i.e. nodeId 0.0 + this.$wrapper.prepend($el); } return $el; }; + // Recursively remove node elements from DOM + Tree.prototype._removeNodeEl = function (node) { + if (!node) return; + + if (node.nodes) { + $.each(node.nodes, $.proxy(function (index, node) { + this._removeNodeEl(node); + }, this)); + } + node.$el.remove(); + }; + // Expand node, rendering it's immediate children Tree.prototype._expandNode = function (node) { if (!node.nodes) return; - var $pEl = node.$el; $.each(node.nodes.slice(0).reverse(), $.proxy(function (index, childNode) { childNode.level = node.level + 1; - this._renderNode(childNode, $pEl); + this._renderNode(childNode, node.$el); }, this)); }; @@ -908,7 +934,7 @@ } // Node level style overrides - $.each(this._nodes, $.proxy(function (index, node) { + $.each(this._orderedNodes, $.proxy(function (index, node) { if (node.color || node.backColor) { var innerStyle = ''; if (node.color) { @@ -917,7 +943,7 @@ if (node.backColor) { innerStyle += 'background-color:' + node.backColor + ';'; } - style += '.node-' + this._elementId + '[data-nodeid="' + node.nodeId + '"]{' + innerStyle + '}'; + style += '.node-' + this._elementId + '[data-nodeId="' + node.nodeId + '"]{' + innerStyle + '}'; } }, this)); @@ -944,15 +970,31 @@ return this._findNodes(pattern, field); }; + + /** + Returns an ordered aarray of node objects. + @return {Array} nodes - An array of all nodes + */ + Tree.prototype.getNodes = function () { + return this._orderedNodes; + }; + /** Returns parent nodes for given nodes, if valid otherwise returns undefined. @param {Array} nodes - An array of nodes @returns {Array} nodes - An array of parent nodes */ Tree.prototype.getParents = function (nodes) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + var parentNodes = []; $.each(nodes, $.proxy(function (index, node) { - parentNodes.push(this._nodes[node.parentId]); + var parentNode = node.parentId ? this._nodes[node.parentId] : false; + if (parentNode) { + parentNodes.push(parentNode); + } }, this)); return parentNodes; }; @@ -963,6 +1005,10 @@ @returns {Array} nodes - An array of sibling nodes */ Tree.prototype.getSiblings = function (nodes) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + var siblingNodes = []; $.each(nodes, $.proxy(function (index, node) { var parent = this.getParents([node]); @@ -1043,13 +1089,167 @@ }; + /** + Add nodes to the tree. + @param {Array} nodes - An array of nodes to add + @param {optional Object} parentNode - The node to which nodes will be added as children + @param {optional number} index - Zero based insert index + @param {optional Object} options + */ + Tree.prototype.addNode = function (nodes, parentNode, index, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (parentNode instanceof Array) { + parentNode = parentNode[0]; + } + + options = $.extend({}, _default.options, options); + + // identify target nodes; either the tree's root or a parent's child nodes + var targetNodes; + if (parentNode && parentNode.nodes) { + targetNodes = parentNode.nodes; + } else if (parentNode) { + targetNodes = parentNode.nodes = []; + } else { + targetNodes = this._tree; + } + + // inserting nodes at specified positions + $.each(nodes, $.proxy(function (i, node) { + var insertIndex = (typeof(index) === 'number') ? (index + i) : (targetNodes.length + 1); + targetNodes.splice(insertIndex, 0, node); + }, this)); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done($.proxy(function () { + if (parentNode && !parentNode.state.expanded) { + this._setExpanded(parentNode, true, options); + } + this._render(); + }, this)); + } + + /** + Add nodes to the tree after given node. + @param {Array} nodes - An array of nodes to add + @param {Object} node - The node to which nodes will be added after + @param {optional Object} options + */ + Tree.prototype.addNodeAfter = function (nodes, node, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (node instanceof Array) { + node = node[0]; + } + + options = $.extend({}, _default.options, options); + + this.addNode(nodes, this.getParents(node)[0], (node.index + 1), options); + } + + /** + Add nodes to the tree before given node. + @param {Array} nodes - An array of nodes to add + @param {Object} node - The node to which nodes will be added before + @param {optional Object} options + */ + Tree.prototype.addNodeBefore = function (nodes, node, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + if (node instanceof Array) { + node = node[0]; + } + + options = $.extend({}, _default.options, options); + + this.addNode(nodes, this.getParents(node)[0], node.index, options); + } + + /** + Removes given nodes from the tree. + @param {Array} nodes - An array of nodes to remove + @param {optional Object} options + */ + Tree.prototype.removeNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + options = $.extend({}, _default.options, options); + + var targetNodes, parentNode; + $.each(nodes, $.proxy(function (index, node) { + + // remove nodes from tree + parentNode = this._nodes[node.parentId]; + if (parentNode) { + targetNodes = parentNode.nodes; + } else { + targetNodes = this._tree; + } + targetNodes.splice(node.index, 1); + + // remove node from DOM + this._removeNodeEl(node); + }, this)); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done(this._render.bind(this)); + }; + + /** + Updates / replaces a given tree node + @param {Object} node - A single node to be replaced + @param {Object} newNode - THe replacement node + @param {optional Object} options + */ + Tree.prototype.updateNode = function (node, newNode, options) { + if (node instanceof Array) { + node = node[0]; + } + + options = $.extend({}, _default.options, options); + + // insert new node + var targetNodes; + var parentNode = this._nodes[node.parentId]; + if (parentNode) { + targetNodes = parentNode.nodes; + } else { + targetNodes = this._tree; + } + targetNodes.splice(node.index, 1, newNode); + + // remove old node from DOM + this._removeNodeEl(node); + + // initialize new state and render changes + this._setInitialStates({nodes: this._tree}, 0) + .done(this._render.bind(this)); + }; + + /** Selects given tree nodes @param {Array} nodes - An array of nodes @param {optional Object} options */ Tree.prototype.selectNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, true, options); }, this)); @@ -1061,7 +1261,12 @@ @param {optional Object} options */ Tree.prototype.unselectNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setSelected(node, false, options); }, this)); @@ -1073,7 +1278,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeSelected = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleSelected(node, options); }, this)); @@ -1097,6 +1307,7 @@ */ Tree.prototype.collapseNode = function (nodes, options) { options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, false, options); }, this)); @@ -1118,7 +1329,12 @@ @param {optional Object} options */ Tree.prototype.expandNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, true, options); if (node.nodes) { @@ -1128,6 +1344,12 @@ }; Tree.prototype._expandLevels = function (nodes, level, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setExpanded(node, (level > 0) ? true : false, options); if (node.nodes) { @@ -1142,7 +1364,12 @@ @param {optional Object} options */ Tree.prototype.revealNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { var parentNode = node; var tmpNode; @@ -1159,7 +1386,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeExpanded = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleExpanded(node, options); }, this)); @@ -1172,6 +1404,7 @@ */ Tree.prototype.checkAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.checked'); $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); @@ -1184,7 +1417,12 @@ @param {optional Object} options */ Tree.prototype.checkNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, true, options); }, this)); @@ -1196,6 +1434,7 @@ */ Tree.prototype.uncheckAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.checked'); $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); @@ -1208,7 +1447,12 @@ @param {optional Object} options */ Tree.prototype.uncheckNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setChecked(node, false, options); }, this)); @@ -1220,7 +1464,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeChecked = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._toggleChecked(node, options); }, this)); @@ -1233,6 +1482,7 @@ */ Tree.prototype.disableAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('false', 'state.disabled'); $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); @@ -1245,7 +1495,12 @@ @param {optional Object} options */ Tree.prototype.disableNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, true, options); }, this)); @@ -1257,6 +1512,7 @@ */ Tree.prototype.enableAll = function (options) { options = $.extend({}, _default.options, options); + var nodes = this._findNodes('true', 'state.disabled'); $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); @@ -1269,7 +1525,12 @@ @param {optional Object} options */ Tree.prototype.enableNode = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, false, options); }, this)); @@ -1281,7 +1542,12 @@ @param {optional Object} options */ Tree.prototype.toggleNodeDisabled = function (nodes, options) { + if (!(nodes instanceof Array)) { + nodes = [nodes]; + } + options = $.extend({}, _default.options, options); + $.each(nodes, $.proxy(function (index, node) { this._setDisabled(node, !node.state.disabled, options); }, this)); @@ -1371,7 +1637,7 @@ Tree.prototype._findNodes = function (pattern, attribute, modifier) { attribute = attribute || 'text'; modifier = modifier || 'g'; - return $.grep(this._nodes, $.proxy(function (node) { + return $.grep(this._orderedNodes, $.proxy(function (node) { var val = this._getNodeValue(node, attribute); if (typeof val === 'string') { return val.match(new RegExp(pattern, modifier)); diff --git a/tests/tests.js b/tests/tests.js index 26e19179d..85f78dbcc 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -558,6 +558,13 @@ equal(nodeParent1.text, 'Parent 1', 'Correct node returned : requested "Parent 1", got "Parent 1"'); }); + test('getNodes', function () { + var tree = init({ data: data }).treeview(true); + var nodes = tree.getNodes(); + ok((nodes instanceof Array), 'Result is an array'); + equal(nodes.length, 9, 'Correct number of nodes returned'); + }); + test('getParents', function () { var tree = init({ data: data }).treeview(true); var nodeChild1 = tree.findNodes('Child 1', 'text'); From 5d59781d32aa41b65b1b95642487ac15dea35bfd Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 18 Jun 2016 12:58:44 +0100 Subject: [PATCH 48/52] Tidy --- README.md | 11 +++++++++++ public/index.html | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f7d6c5b84..c71660494 100644 --- a/README.md +++ b/README.md @@ -409,11 +409,21 @@ $('#tree').data('treeview') ``` > A better approach, if you plan a lot of interaction. +If you intend to make multiple API calls, store a reference to the treeview instance. + +```javascript +var tree = $('#tree').treeview(true); +tree.method1(args); +tree.method2(args); +``` + ### List of Methods The following is a list of all available methods. +> All methods that all declare argument `nodes` will accept either a single node, or an Array of nodes. + #### addNode(nodes, parentNode, index, options) Add nodes to the tree. @@ -863,6 +873,7 @@ $('#tree').on('nodeSelected', function(event, data) { `searchCleared (event, results)` - After search results are cleared +> All events that emit multiple nodes, do so as an object collection not an array. This is due to limitations of jQuery in cloning plain JavaScript objects. If you need to an Array of nodes you'll need to reduce the object back into an array. ## Copyright and Licensing diff --git a/public/index.html b/public/index.html index 7dd03eb0c..a008c03aa 100644 --- a/public/index.html +++ b/public/index.html @@ -462,7 +462,6 @@

                                                                                                                                }); $('#treeview4').treeview({ - color: "#428bca", data: defaultData }); From a211f710f445cd9891cd9c2f8a5a76698273b3bd Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 18 Jun 2016 14:32:30 +0100 Subject: [PATCH 49/52] Update package dependencies Resolves #223 --- Gruntfile.js | 18 ++++++++---------- bower.json | 5 +---- dist/bootstrap-treeview.min.js | 2 +- package.json | 24 +++++++++++------------- public/css/bootstrap-treeview.css | 8 ++++---- public/js/bootstrap-treeview.js | 2 +- src/css/bootstrap-treeview.css | 8 ++++---- src/js/bootstrap-treeview.js | 2 +- tests/lib/bootstrap-treeview.css | 8 ++++---- tests/lib/bootstrap-treeview.js | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 80a001d5b..3bb467955 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,11 +1,11 @@ module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), // the package file to use - + uglify: { files: { - expand: true, - flatten: true, + expand: true, + flatten: true, src: 'src/js/*.js', dest: 'dist', ext: '.min.js' @@ -32,18 +32,16 @@ module.exports = function(grunt) { }, copy: { - main: { + main: { files: [ - // copy dist to tests - // { expand: true, cwd: 'dist', src: '*', dest: 'tests/lib/' }, + // setup tests { expand: true, cwd: 'src/css', src: '*', dest: 'tests/lib/' }, { expand: true, cwd: 'src/js', src: '*', dest: 'tests/lib/' }, - // copy latest libs to tests { expand: true, cwd: 'public/bower_components/jquery', src: 'jquery.js', dest: 'tests/lib/' }, { expand: true, cwd: 'public/bower_components/bootstrap-datepicker/js', src: 'bootstrap-datepicker.js', dest: 'tests/lib/' }, - // copy src to example + // setup public { expand: true, cwd: 'src/css', src: '*', dest: 'public/css/' }, - { expand: true, cwd: 'src/js', src: '*', dest: 'public/js/' } + { expand: true, cwd: 'src/js', src: '*', dest: 'public/js/' }, ] } } @@ -57,6 +55,6 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-copy'); // register one or more task lists (you should ALWAYS have a "default" task list) - grunt.registerTask('default', ['uglify','cssmin', 'copy', 'qunit', 'watch']); + grunt.registerTask('default', ['uglify', 'cssmin', 'copy', 'qunit', 'watch']); grunt.registerTask('test', 'qunit'); }; diff --git a/bower.json b/bower.json index 1b009d7da..696635607 100644 --- a/bower.json +++ b/bower.json @@ -3,10 +3,7 @@ "description": "Tree View for Twitter Bootstrap", "version": "1.2.0", "homepage": "https://github.com/jonmiles/bootstrap-treeview", - "main": [ - "dist/bootstrap-treeview.min.js", - "dist/bootstrap-treeview.min.css" - ], + "main": "dist/bootstrap-treeview.min.js", "keywords": [ "twitter", "bootstrap", diff --git a/dist/bootstrap-treeview.min.js b/dist/bootstrap-treeview.min.js index bb438f403..e86b764f4 100644 --- a/dist/bootstrap-treeview.min.js +++ b/dist/bootstrap-treeview.min.js @@ -1 +1 @@ -!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getNodes:a.proxy(this.getNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),addNode:a.proxy(this.addNode,this),addNodeAfter:a.proxy(this.addNodeAfter,this),addNodeBefore:a.proxy(this.addNodeBefore,this),removeNode:a.proxy(this.removeNode,this),updateNode:a.proxy(this.updateNode,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(a){return this._setInitialStates({nodes:a},0)},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c){return this._nodes={},a.when.apply(this,this._setInitialState(b,c)).done(a.proxy(function(){this._orderedNodes=this._sortNodes(),this._triggerEvent("initialized",this._orderedNodes,f.options)},this))},g.prototype._setInitialState=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b;return a.each(b.nodes,a.proxy(function(b,f){var g=new a.Deferred;d.push(g.promise()),f.level=c,f.index=b,f.nodeId=e&&e.nodeId?e.nodeId+"."+f.index:c-1+"."+f.index,f.parentId=e.nodeId,f.hasOwnProperty("selectable")||(f.selectable=!0),f.state=f.state||{},f.state.hasOwnProperty("checked")||(f.state.checked=!1),f.state.hasOwnProperty("disabled")||(f.state.disabled=!1),f.state.hasOwnProperty("expanded")||(!f.state.disabled&&c0?f.state.expanded=!0:f.state.expanded=!1),f.state.hasOwnProperty("selected")||(f.state.selected=!1),e&&e.state&&e.state.expanded||c<=this._options.levels?f.state.visible=!0:f.state.visible=!1,f.nodes&&(f.nodes.length>0?this._setInitialState(f,c,d):delete f.nodes),this._nodes[f.nodeId]=f,g.resolve()},this)),d}},g.prototype._sortNodes=function(){return a.map(Object.keys(this._nodes).sort(),a.proxy(function(a,b){return this._nodes[a]},this))},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeId"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0);var b;a.each(this._orderedNodes,a.proxy(function(a,c){this._renderNode(c,b),b=c},this)),this._triggerEvent("rendered",this._orderedNodes,f.options)},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():b.$el=this._newNodeEl(b,c).addClass("node-"+this._elementId),b.$el.attr("data-nodeId",b.nodeId);for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._orderedNodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeId="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                                  ',node:'
                                                                                                                                • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getNodes=function(){return this._orderedNodes},g.prototype.getParents=function(b){b instanceof Array||(b=[b]);var c=[];return a.each(b,a.proxy(function(a,b){var d=b.parentId?this._nodes[b.parentId]:!1;d&&c.push(d)},this)),c},g.prototype.getSiblings=function(b){b instanceof Array||(b=[b]);var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.addNode=function(b,c,d,e){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),e=a.extend({},f.options,e);var g;g=c&&c.nodes?c.nodes:c?c.nodes=[]:this._tree,a.each(b,a.proxy(function(a,b){var c="number"==typeof d?d+a:g.length+1;g.splice(c,0,b)},this)),this._setInitialStates({nodes:this._tree},0).done(a.proxy(function(){c&&!c.state.expanded&&this._setExpanded(c,!0,e),this._render()},this))},g.prototype.addNodeAfter=function(b,c,d){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),d=a.extend({},f.options,d),this.addNode(b,this.getParents(c)[0],c.index+1,d)},g.prototype.addNodeBefore=function(b,c,d){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),d=a.extend({},f.options,d),this.addNode(b,this.getParents(c)[0],c.index,d)},g.prototype.removeNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c);var d,e;a.each(b,a.proxy(function(a,b){e=this._nodes[b.parentId],d=e?e.nodes:this._tree,d.splice(b.index,1),this._removeNodeEl(b)},this)),this._setInitialStates({nodes:this._tree},0).done(this._render.bind(this))},g.prototype.updateNode=function(b,c,d){b instanceof Array&&(b=b[0]),d=a.extend({},f.options,d);var e,g=this._nodes[b.parentId];e=g?g.nodes:this._tree,e.splice(b.index,1,c),this._removeNodeEl(b),this._setInitialStates({nodes:this._tree},0).done(this._render.bind(this))},g.prototype.selectNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){b instanceof Array||(b=[b]),d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0?!0:!1,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._orderedNodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,preventUnselect:!1,onLoading:d,onLoadingFailed:d,onInitialized:d,onNodeRendered:d,onRendered:d,onDestroyed:d,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0},f.dataUrl={method:"GET",dataType:"json",cache:!1};var g=function(b,c){return this.$element=a(b),this._elementId=b.id,this._styleId=this._elementId+"-style",this._init(c),{options:this._options,init:a.proxy(this._init,this),remove:a.proxy(this._remove,this),findNodes:a.proxy(this.findNodes,this),getNodes:a.proxy(this.getNodes,this),getParents:a.proxy(this.getParents,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),addNode:a.proxy(this.addNode,this),addNodeAfter:a.proxy(this.addNodeAfter,this),addNodeBefore:a.proxy(this.addNodeBefore,this),removeNode:a.proxy(this.removeNode,this),updateNode:a.proxy(this.updateNode,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype._init=function(b){this._tree=[],this._initialized=!1,this._options=a.extend({},f.settings,b),this._destroy(),this._subscribeEvents(),this._triggerEvent("loading",null,f.options),this._load(b).then(a.proxy(function(b){return this._tree=a.extend(!0,[],b)},this),a.proxy(function(a){this._triggerEvent("loadingFailed",a,f.options)},this)).then(a.proxy(function(a){return this._setInitialStates({nodes:a},0)},this)).then(a.proxy(function(){this._render()},this))},g.prototype._load=function(b){var c=new a.Deferred;return b.data?this._loadLocalData(b,c):b.dataUrl&&this._loadRemoteData(b,c),c.promise()},g.prototype._loadRemoteData=function(b,c){a.ajax(a.extend(!0,{},f.dataUrl,b.dataUrl)).done(function(a){c.resolve(a)}).fail(function(a,b,d){c.reject(d)})},g.prototype._loadLocalData=function(b,c){c.resolve("string"==typeof b.data?a.parseJSON(b.data):a.extend(!0,[],b.data))},g.prototype._remove=function(){this._destroy(),a.removeData(this,e),a("#"+this._styleId).remove()},g.prototype._destroy=function(){this._initialized&&(this._initialized=!1,this._triggerEvent("destroyed",null,f.options),this._unsubscribeEvents(),this.$wrapper.remove(),this.$wrapper=null)},g.prototype._unsubscribeEvents=function(){this.$element.off("loading"),this.$element.off("loadingFailed"),this.$element.off("initialized"),this.$element.off("nodeRendered"),this.$element.off("rendered"),this.$element.off("destroyed"),this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype._subscribeEvents=function(){this._unsubscribeEvents(),"function"==typeof this._options.onLoading&&this.$element.on("loading",this._options.onLoading),"function"==typeof this._options.onLoadingFailed&&this.$element.on("loadingFailed",this._options.onLoadingFailed),"function"==typeof this._options.onInitialized&&this.$element.on("initialized",this._options.onInitialized),"function"==typeof this._options.onNodeRendered&&this.$element.on("nodeRendered",this._options.onNodeRendered),"function"==typeof this._options.onRendered&&this.$element.on("rendered",this._options.onRendered),"function"==typeof this._options.onDestroyed&&this.$element.on("destroyed",this._options.onDestroyed),this.$element.on("click",a.proxy(this._clickHandler,this)),"function"==typeof this._options.onNodeChecked&&this.$element.on("nodeChecked",this._options.onNodeChecked),"function"==typeof this._options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this._options.onNodeCollapsed),"function"==typeof this._options.onNodeDisabled&&this.$element.on("nodeDisabled",this._options.onNodeDisabled),"function"==typeof this._options.onNodeEnabled&&this.$element.on("nodeEnabled",this._options.onNodeEnabled),"function"==typeof this._options.onNodeExpanded&&this.$element.on("nodeExpanded",this._options.onNodeExpanded),"function"==typeof this._options.onNodeSelected&&this.$element.on("nodeSelected",this._options.onNodeSelected),"function"==typeof this._options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this._options.onNodeUnchecked),"function"==typeof this._options.onNodeUnselected&&this.$element.on("nodeUnselected",this._options.onNodeUnselected),"function"==typeof this._options.onSearchComplete&&this.$element.on("searchComplete",this._options.onSearchComplete),"function"==typeof this._options.onSearchCleared&&this.$element.on("searchCleared",this._options.onSearchCleared)},g.prototype._triggerEvent=function(b,c,d){d&&!d.silent&&this.$element.trigger(b,a.extend(!0,{},c))},g.prototype._setInitialStates=function(b,c){return this._nodes={},a.when.apply(this,this._setInitialState(b,c)).done(a.proxy(function(){this._orderedNodes=this._sortNodes(),this._triggerEvent("initialized",this._orderedNodes,f.options)},this))},g.prototype._setInitialState=function(b,c,d){if(b.nodes){c+=1,d=d||[];var e=b;return a.each(b.nodes,a.proxy(function(b,f){var g=new a.Deferred;d.push(g.promise()),f.level=c,f.index=b,f.nodeId=e&&e.nodeId?e.nodeId+"."+f.index:c-1+"."+f.index,f.parentId=e.nodeId,f.hasOwnProperty("selectable")||(f.selectable=!0),f.state=f.state||{},f.state.hasOwnProperty("checked")||(f.state.checked=!1),f.state.hasOwnProperty("disabled")||(f.state.disabled=!1),f.state.hasOwnProperty("expanded")||(!f.state.disabled&&c0?f.state.expanded=!0:f.state.expanded=!1),f.state.hasOwnProperty("selected")||(f.state.selected=!1),e&&e.state&&e.state.expanded||c<=this._options.levels?f.state.visible=!0:f.state.visible=!1,f.nodes&&(f.nodes.length>0?this._setInitialState(f,c,d):delete f.nodes),this._nodes[f.nodeId]=f,g.resolve()},this)),d}},g.prototype._sortNodes=function(){return a.map(Object.keys(this._nodes).sort(),a.proxy(function(a,b){return this._nodes[a]},this))},g.prototype._clickHandler=function(b){var c=a(b.target),d=this.targetNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?this._toggleExpanded(d,a.extend({},f.options)):-1!==e.indexOf("check-icon")?this._toggleChecked(d,a.extend({},f.options)):d.selectable?this._toggleSelected(d,a.extend({},f.options)):this._toggleExpanded(d,a.extend({},f.options))}},g.prototype.targetNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeId"),c=this._nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype._toggleExpanded=function(a,b){a&&this._setExpanded(a,!a.state.expanded,b)},g.prototype._setExpanded=function(b,c,d){d&&c===b.state.expanded||(c&&b.nodes?(b.state.expanded=!0,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.expandIcon).addClass(this._options.collapseIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!0,d)},this)),this._triggerEvent("nodeExpanded",b,d)):c||(b.state.expanded=!1,b.$el&&b.$el.children("span.expand-icon").removeClass(this._options.collapseIcon).addClass(this._options.expandIcon),b.nodes&&d&&a.each(b.nodes,a.proxy(function(a,b){this._setVisible(b,!1,d),this._setExpanded(b,!1,d)},this)),this._triggerEvent("nodeCollapsed",b,d)))},g.prototype._setVisible=function(a,b,c){c&&b===a.state.visible||(b?(a.state.visible=!0,a.$el&&a.$el.removeClass("node-hidden")):(a.state.visible=!1,a.$el&&a.$el.addClass("node-hidden")))},g.prototype._toggleSelected=function(a,b){return a?(this._setSelected(a,!a.state.selected,b),this):void 0},g.prototype._setSelected=function(b,c,d){if(!d||c!==b.state.selected){if(c)this._options.multiSelect||a.each(this._findNodes("true","state.selected"),a.proxy(function(b,c){this._setSelected(c,!1,a.extend(d,{unselecting:!0}))},this)),b.state.selected=!0,b.$el&&(b.$el.addClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.icon||this._options.nodeIcon).addClass(b.selectedIcon||this._options.selectedIcon)),this._triggerEvent("nodeSelected",b,d);else{if(this._options.preventUnselect&&d&&!d.unselecting&&1===this._findNodes("true","state.selected").length)return this;b.state.selected=!1,b.$el&&(b.$el.removeClass("node-selected"),(b.selectedIcon||this._options.selectedIcon)&&b.$el.children("span.node-icon").removeClass(b.selectedIcon||this._options.selectedIcon).addClass(b.icon||this._options.nodeIcon)),this._triggerEvent("nodeUnselected",b,d)}return this}},g.prototype._toggleChecked=function(a,b){a&&this._setChecked(a,!a.state.checked,b)},g.prototype._setChecked=function(a,b,c){c&&b===a.state.checked||(b?(a.state.checked=!0,a.$el&&(a.$el.addClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.uncheckedIcon).addClass(this._options.checkedIcon)),this._triggerEvent("nodeChecked",a,c)):(a.state.checked=!1,a.$el&&(a.$el.removeClass("node-checked"),a.$el.children("span.check-icon").removeClass(this._options.checkedIcon).addClass(this._options.uncheckedIcon)),this._triggerEvent("nodeUnchecked",a,c)))},g.prototype._setDisabled=function(a,b,c){c&&b===a.state.disabled||(b?(a.state.disabled=!0,this._setSelected(a,!1,c),this._setChecked(a,!1,c),this._setExpanded(a,!1,c),a.$el&&a.$el.addClass("node-disabled"),this._triggerEvent("nodeDisabled",a,c)):(a.state.disabled=!1,a.$el&&a.$el.removeClass("node-disabled"),this._triggerEvent("nodeEnabled",a,c)))},g.prototype._setSearchResult=function(a,b,c){c&&b===a.searchResult||(b?(a.searchResult=!0,a.$el&&a.$el.addClass("node-result")):(a.searchResult=!1,a.$el&&a.$el.removeClass("node-result")))},g.prototype._render=function(){this._initialized||(this.$wrapper=a(this._template.tree),this.$element.empty().addClass(e).append(this.$wrapper),this._injectStyle(),this._initialized=!0);var b;a.each(this._orderedNodes,a.proxy(function(a,c){this._renderNode(c,b),b=c},this)),this._triggerEvent("rendered",this._orderedNodes,f.options)},g.prototype._renderNode=function(b,c){if(b){b.$el?b.$el.empty():b.$el=this._newNodeEl(b,c).addClass("node-"+this._elementId),b.$el.attr("data-nodeId",b.nodeId);for(var d=0;d '+this._buildStyle()+" ").appendTo("head")},g.prototype._buildStyle=function(){var b=".node-"+this._elementId+"{";if(this._options.color&&(b+="color:"+this._options.color+";"),this._options.backColor&&(b+="background-color:"+this._options.backColor+";"),this._options.showBorder?this._options.borderColor&&(b+="border:1px solid "+this._options.borderColor+";"):b+="border:none;",b+="}",this._options.onhoverColor&&(b+=".node-"+this._elementId+":not(.node-disabled):hover{background-color:"+this._options.onhoverColor+";}"),this._options.highlightSearchResults&&(this._options.searchResultColor||this._options.searchResultBackColor)){var c="";this._options.searchResultColor&&(c+="color:"+this._options.searchResultColor+";"),this._options.searchResultBackColor&&(c+="background-color:"+this._options.searchResultBackColor+";"),b+=".node-"+this._elementId+".node-result{"+c+"}",b+=".node-"+this._elementId+".node-result:hover{"+c+"}"}if(this._options.highlightSelected&&(this._options.selectedColor||this._options.selectedBackColor)){var c="";this._options.selectedColor&&(c+="color:"+this._options.selectedColor+";"),this._options.selectedBackColor&&(c+="background-color:"+this._options.selectedBackColor+";"),b+=".node-"+this._elementId+".node-selected{"+c+"}",b+=".node-"+this._elementId+".node-selected:hover{"+c+"}"}return a.each(this._orderedNodes,a.proxy(function(a,c){if(c.color||c.backColor){var d="";c.color&&(d+="color:"+c.color+";"),c.backColor&&(d+="background-color:"+c.backColor+";"),b+=".node-"+this._elementId+'[data-nodeId="'+c.nodeId+'"]{'+d+"}"}},this)),this._css+b},g.prototype._template={tree:'
                                                                                                                                    ',node:'
                                                                                                                                  • ',indent:'',icon:'',badge:''},g.prototype._css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.findNodes=function(a,b){return this._findNodes(a,b)},g.prototype.getNodes=function(){return this._orderedNodes},g.prototype.getParents=function(b){b instanceof Array||(b=[b]);var c=[];return a.each(b,a.proxy(function(a,b){var d=b.parentId?this._nodes[b.parentId]:!1;d&&c.push(d)},this)),c},g.prototype.getSiblings=function(b){b instanceof Array||(b=[b]);var c=[];return a.each(b,a.proxy(function(a,b){var d=this.getParents([b]),e=d[0]?d[0].nodes:this._tree;c=e.filter(function(a){return a.nodeId!==b.nodeId})},this)),a.map(c,function(a){return a})},g.prototype.getSelected=function(){return this._findNodes("true","state.selected")},g.prototype.getUnselected=function(){return this._findNodes("false","state.selected")},g.prototype.getExpanded=function(){return this._findNodes("true","state.expanded")},g.prototype.getCollapsed=function(){return this._findNodes("false","state.expanded")},g.prototype.getChecked=function(){return this._findNodes("true","state.checked")},g.prototype.getUnchecked=function(){return this._findNodes("false","state.checked")},g.prototype.getDisabled=function(){return this._findNodes("true","state.disabled")},g.prototype.getEnabled=function(){return this._findNodes("false","state.disabled")},g.prototype.addNode=function(b,c,d,e){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),e=a.extend({},f.options,e);var g;g=c&&c.nodes?c.nodes:c?c.nodes=[]:this._tree,a.each(b,a.proxy(function(a,b){var c="number"==typeof d?d+a:g.length+1;g.splice(c,0,b)},this)),this._setInitialStates({nodes:this._tree},0).done(a.proxy(function(){c&&!c.state.expanded&&this._setExpanded(c,!0,e),this._render()},this))},g.prototype.addNodeAfter=function(b,c,d){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),d=a.extend({},f.options,d),this.addNode(b,this.getParents(c)[0],c.index+1,d)},g.prototype.addNodeBefore=function(b,c,d){b instanceof Array||(b=[b]),c instanceof Array&&(c=c[0]),d=a.extend({},f.options,d),this.addNode(b,this.getParents(c)[0],c.index,d)},g.prototype.removeNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c);var d,e;a.each(b,a.proxy(function(a,b){e=this._nodes[b.parentId],d=e?e.nodes:this._tree,d.splice(b.index,1),this._removeNodeEl(b)},this)),this._setInitialStates({nodes:this._tree},0).done(this._render.bind(this))},g.prototype.updateNode=function(b,c,d){b instanceof Array&&(b=b[0]),d=a.extend({},f.options,d);var e,g=this._nodes[b.parentId];e=g?g.nodes:this._tree,e.splice(b.index,1,c),this._removeNodeEl(b),this._setInitialStates({nodes:this._tree},0).done(this._render.bind(this))},g.prototype.selectNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!0,c)},this))},g.prototype.unselectNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setSelected(b,!1,c)},this))},g.prototype.toggleNodeSelected=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleSelected(b,c)},this))},g.prototype.collapseAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.collapseNode(this._tree,b)},g.prototype.collapseNode=function(b,c){c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!1,c)},this))},g.prototype.expandAll=function(b){b=a.extend({},f.options,b),b.levels=b.levels||999,this.expandNode(this._tree,b)},g.prototype.expandNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setExpanded(b,!0,c),b.nodes&&this._expandLevels(b.nodes,c.levels-1,c)},this))},g.prototype._expandLevels=function(b,c,d){b instanceof Array||(b=[b]),d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this._setExpanded(b,c>0,d),b.nodes&&this._expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){for(var d,e=b;d=this.getParents([e])[0];)e=d,this._setExpanded(e,!0,c)},this))},g.prototype.toggleNodeExpanded=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleExpanded(b,c)},this))},g.prototype.checkAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!0,b)},this))},g.prototype.checkNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!0,c)},this))},g.prototype.uncheckAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.checked");a.each(c,a.proxy(function(a,c){this._setChecked(c,!1,b)},this))},g.prototype.uncheckNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setChecked(b,!1,c)},this))},g.prototype.toggleNodeChecked=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._toggleChecked(b,c)},this))},g.prototype.disableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("false","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!0,b)},this))},g.prototype.disableNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!0,c)},this))},g.prototype.enableAll=function(b){b=a.extend({},f.options,b);var c=this._findNodes("true","state.disabled");a.each(c,a.proxy(function(a,c){this._setDisabled(c,!1,b)},this))},g.prototype.enableNode=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!1,c)},this))},g.prototype.toggleNodeDisabled=function(b,c){b instanceof Array||(b=[b]),c=a.extend({},f.options,c),a.each(b,a.proxy(function(a,b){this._setDisabled(b,!b.state.disabled,c)},this))},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c);var d=this._getSearchResults(),e=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var g="g";c.ignoreCase&&(g+="i"),e=this._findNodes(b,"text",g)}return a.each(this._diffArray(e,d),a.proxy(function(a,b){this._setSearchResult(b,!1,c)},this)),a.each(this._diffArray(d,e),a.proxy(function(a,b){this._setSearchResult(b,!0,c)},this)),e&&c.revealResults&&this.revealNode(e),this._triggerEvent("searchComplete",e,c),e},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this._getSearchResults(),a.proxy(function(a,c){this._setSearchResult(c,!1,b)},this));this._triggerEvent("searchCleared",c,b)},g.prototype._getSearchResults=function(){return this._findNodes("true","searchResult")},g.prototype._diffArray=function(b,c){var d=[];return a.grep(c,function(c){-1===a.inArray(c,b)&&d.push(c)}),d},g.prototype._findNodes=function(b,c,d){return c=c||"text",d=d||"g",a.grep(this._orderedNodes,a.proxy(function(a){var e=this._getNodeValue(a,c);return"string"==typeof e?e.match(new RegExp(b,d)):void 0},this))},g.prototype._getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this._getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/package.json b/package.json index cf390ea19..03d09a172 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,7 @@ "url": "https://github.com/jonmiles/bootstrap-treeview/blob/master/LICENSE" } ], - "main": [ - "dist/bootstrap-treeview.min.js", - "dist/bootstrap-treeview.min.css" - ], + "main": "src/bootstrap-treeview.js", "scripts": { "install": "bower install", "start": "node app", @@ -32,18 +29,19 @@ "node": ">= 0.10.0" }, "dependencies": { - "express": "3.4.x", - "ejs": "2.2.x", - "phantomjs": "1.9.x" + "bootstrap": "3.3.x", + "jquery": "3.0.x" }, "devDependencies": { "bower": "1.3.x", - "grunt": "0.4.x", - "grunt-contrib-copy": "0.7.x", - "grunt-contrib-cssmin": "0.12.x", - "grunt-contrib-qunit": "1.2.x", - "grunt-contrib-uglify": "0.7.x", - "grunt-contrib-watch": "0.6.x" + "express": "3.4.x", + "grunt": "^1.0.1", + "grunt-contrib-copy": "^0.7.0", + "grunt-contrib-cssmin": "^0.12.3", + "grunt-contrib-qunit": "^1.2.0", + "grunt-contrib-uglify": "^0.7.0", + "grunt-contrib-watch": "^0.6.1", + "phantomjs": "^2.1.7" }, "keywords": [ "twitter", diff --git a/public/css/bootstrap-treeview.css b/public/css/bootstrap-treeview.css index 6378f2d01..bccab55ab 100644 --- a/public/css/bootstrap-treeview.css +++ b/public/css/bootstrap-treeview.css @@ -1,9 +1,9 @@ /* ========================================================= - * bootstrap-treeview.css v1.2.0 + * bootstrap-treeview.css v2.0.0 * ========================================================= - * Copyright 2013 Jonathan Miles + * Copyright 2013 Jonathan Miles * Project URL : http://www.jondmiles.com/bootstrap-treeview - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -38,4 +38,4 @@ .treeview .node-hidden { display: none; -} \ No newline at end of file +} diff --git a/public/js/bootstrap-treeview.js b/public/js/bootstrap-treeview.js index a2292697a..820a1f941 100644 --- a/public/js/bootstrap-treeview.js +++ b/public/js/bootstrap-treeview.js @@ -1,5 +1,5 @@ /* ========================================================= - * bootstrap-treeview.js v1.2.0 + * bootstrap-treeview.js v2.0.0 * ========================================================= * Copyright 2013 Jonathan Miles * Project URL : http://www.jondmiles.com/bootstrap-treeview diff --git a/src/css/bootstrap-treeview.css b/src/css/bootstrap-treeview.css index 6378f2d01..bccab55ab 100644 --- a/src/css/bootstrap-treeview.css +++ b/src/css/bootstrap-treeview.css @@ -1,9 +1,9 @@ /* ========================================================= - * bootstrap-treeview.css v1.2.0 + * bootstrap-treeview.css v2.0.0 * ========================================================= - * Copyright 2013 Jonathan Miles + * Copyright 2013 Jonathan Miles * Project URL : http://www.jondmiles.com/bootstrap-treeview - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -38,4 +38,4 @@ .treeview .node-hidden { display: none; -} \ No newline at end of file +} diff --git a/src/js/bootstrap-treeview.js b/src/js/bootstrap-treeview.js index a2292697a..820a1f941 100644 --- a/src/js/bootstrap-treeview.js +++ b/src/js/bootstrap-treeview.js @@ -1,5 +1,5 @@ /* ========================================================= - * bootstrap-treeview.js v1.2.0 + * bootstrap-treeview.js v2.0.0 * ========================================================= * Copyright 2013 Jonathan Miles * Project URL : http://www.jondmiles.com/bootstrap-treeview diff --git a/tests/lib/bootstrap-treeview.css b/tests/lib/bootstrap-treeview.css index 6378f2d01..bccab55ab 100644 --- a/tests/lib/bootstrap-treeview.css +++ b/tests/lib/bootstrap-treeview.css @@ -1,9 +1,9 @@ /* ========================================================= - * bootstrap-treeview.css v1.2.0 + * bootstrap-treeview.css v2.0.0 * ========================================================= - * Copyright 2013 Jonathan Miles + * Copyright 2013 Jonathan Miles * Project URL : http://www.jondmiles.com/bootstrap-treeview - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -38,4 +38,4 @@ .treeview .node-hidden { display: none; -} \ No newline at end of file +} diff --git a/tests/lib/bootstrap-treeview.js b/tests/lib/bootstrap-treeview.js index a2292697a..820a1f941 100644 --- a/tests/lib/bootstrap-treeview.js +++ b/tests/lib/bootstrap-treeview.js @@ -1,5 +1,5 @@ /* ========================================================= - * bootstrap-treeview.js v1.2.0 + * bootstrap-treeview.js v2.0.0 * ========================================================= * Copyright 2013 Jonathan Miles * Project URL : http://www.jondmiles.com/bootstrap-treeview From 8b3dca90883dbc27906c5b699fc0b255515c6162 Mon Sep 17 00:00:00 2001 From: jonmiles Date: Sat, 18 Jun 2016 15:26:26 +0100 Subject: [PATCH 50/52] Remove bower from build process / dependencies --- .bowerrc | 3 - .gitignore | 2 +- .travis.yml | 9 +- Gruntfile.js | 5 +- bower.json | 1 - package.json | 11 +- public/example-dom.html | 8 +- public/index.html | 4 +- tests/lib/jquery.js | 10457 ++++++++++++++++++++------------------ 9 files changed, 5440 insertions(+), 5060 deletions(-) delete mode 100644 .bowerrc diff --git a/.bowerrc b/.bowerrc deleted file mode 100644 index 38b8a96cc..000000000 --- a/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "public/bower_components" -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c7b9408e4..77d664054 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ node_modules/ -public/bower_components/ +public/libs diff --git a/.travis.yml b/.travis.yml index 367fa5cd8..447d8e029 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,15 @@ language: node_js node_js: - - "0.11" - "0.10" + - "0.11" + - "0.12" + - "4" + - "5" + - "6" before_script: - npm install -g grunt-cli - npm install - - bower install -script: grunt test --verbose --force \ No newline at end of file +script: grunt test --verbose --force diff --git a/Gruntfile.js b/Gruntfile.js index 3bb467955..a495f9555 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -37,11 +37,12 @@ module.exports = function(grunt) { // setup tests { expand: true, cwd: 'src/css', src: '*', dest: 'tests/lib/' }, { expand: true, cwd: 'src/js', src: '*', dest: 'tests/lib/' }, - { expand: true, cwd: 'public/bower_components/jquery', src: 'jquery.js', dest: 'tests/lib/' }, - { expand: true, cwd: 'public/bower_components/bootstrap-datepicker/js', src: 'bootstrap-datepicker.js', dest: 'tests/lib/' }, + { expand: true, cwd: 'node_modules/jquery/dist', src: 'jquery.js', dest: 'tests/lib/' }, // setup public { expand: true, cwd: 'src/css', src: '*', dest: 'public/css/' }, { expand: true, cwd: 'src/js', src: '*', dest: 'public/js/' }, + { expand: true, cwd: 'node_modules/bootstrap/dist/', src: '**/*', dest: 'public/libs/bootstrap/' }, + { expand: true, cwd: 'node_modules/jquery/dist/', src: '*', dest: 'public/libs/jquery' } ] } } diff --git a/bower.json b/bower.json index 696635607..c20725b49 100644 --- a/bower.json +++ b/bower.json @@ -18,7 +18,6 @@ "ignore": [ "**/.*", "node_modules", - "bower_components", "test", "tests" ], diff --git a/package.json b/package.json index 03d09a172..cc8e3b5c5 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ ], "main": "src/bootstrap-treeview.js", "scripts": { - "install": "bower install", "start": "node app", "test": "grunt test" }, @@ -30,17 +29,17 @@ }, "dependencies": { "bootstrap": "3.3.x", - "jquery": "3.0.x" + "jquery": "2.1.x" }, "devDependencies": { "bower": "1.3.x", "express": "3.4.x", "grunt": "^1.0.1", - "grunt-contrib-copy": "^0.7.0", - "grunt-contrib-cssmin": "^0.12.3", + "grunt-contrib-copy": "^1.0.0", + "grunt-contrib-cssmin": "^1.0.1", "grunt-contrib-qunit": "^1.2.0", - "grunt-contrib-uglify": "^0.7.0", - "grunt-contrib-watch": "^0.6.1", + "grunt-contrib-uglify": "^1.0.1", + "grunt-contrib-watch": "^1.0.0", "phantomjs": "^2.1.7" }, "keywords": [ diff --git a/public/example-dom.html b/public/example-dom.html index 8fe5f75b6..f51e239dd 100644 --- a/public/example-dom.html +++ b/public/example-dom.html @@ -2,7 +2,7 @@ Bootstrap Tree View - + @@ -16,12 +16,12 @@

                                                                                                                                    Bootstrap Tree View - DOM Tree

                                                                                                                                    - + +