📄 tree-node.js
字号:
/** * Default JSON format: * { * label: [string], // node label. It will be clickable. Required. * isExpanded: [boolean, optional], // if this branch is expanded. Default value - false. This option will be ignored if "children" section is null * isSelected: [boolean, optional], // if this node is selected. Default value - false. * isChecked: [boolean, optional], // if tree displays checkboxes for all items - if this is true - checkbox will be checked * expandedIcon: [string, optional], // string with IMG tag. This image will be shown when branch is expanded. This option will be ignored if "children" section is null. * collapsedIcon: [string, optional], // string with IMG tag. This image will be shown when branch is collapsed. This option will be ignored if "children" section is null. * fetchingIcon: [string, optional], // string with IMG tag. This image will be shown when branch is fetching its content. This option will be ignored if "children" section is null. * elementIcon: [string, optional], // string with IMG tag. This image will be shown for single node (without branch) * source: [string, optional], // if given - on expand tree will fetch content from given source. If "children" section is null - it will be put to empty array. * sourceType: [string, optional], // type of source that will be fetched. See Zapatec.Widget documentation for examples. * loadAlways: [boolean, optional], // if true - node children will be reloaded on each expand. Default - false. * attributes: { * attributeName: atrtibuteValue [string, optional], // this value will be added to TD element that contains node content. * ... * }, * children: [ // child nodes. If null - no +/- sign will be displayed. * ... * ] * } * <strong>HTML:</strong> * Common HTML list - <UL><LI>...</LI>...</UL> * <strong>XML:</strong> * TODO*/Zapatec.Tree.Node = function(objArgs){ Zapatec.Tree.Node.SUPERconstructor.call(this, objArgs);};/** * Unique static id of the widget class. Gives ability for Zapatec#inherit to * determine and store path to this file correctly when it is included using * Zapatec#include. When this file is included using Zapatec#include or path * to this file is gotten using Zapatec#getPath, this value must be specified * as script id. * @private */Zapatec.Tree.Node.id = "Zapatec.Tree.Node";// Inherit SuperClassZapatec.inherit(Zapatec.Tree.Node, Zapatec.Widget);/** * Configures tree. Gets called from parent init method. * * @private * @param {object} objArgs User configuration */Zapatec.Tree.Node.prototype.configure = function(objArgs) { this.defineConfigOption('theme', null); // node has no themes this.defineConfigOption('tree', null); // reference to parent Zapatec.Tree object this.defineConfigOption('parentNode', null); // reference to parent Zapatec.Tree.Node object this.defineConfigOption('level'); // level of this node this.defineConfigOption('isRootNode', false); // is this node a tree root node (actually virtual node). Do not document this confg option Zapatec.Tree.Node.SUPERclass.configure.call(this, objArgs); if(this.config.tree == null){ Zapatec.Log({description: "No reference to parent Zapatec.Tree instance! Aborting."}); throw("No reference to parent Zapatec.Tree instance! Aborting."); }};/** * @private * Initializes tree. * @param {object} objArgs User configuration */Zapatec.Tree.Node.prototype.init = function(config) { this.expandedIcon = null; // this icon will be displayed for expanded branch this.collapsedIcon = null; // this icon will be displayed for collapsed branch this.fetchingIcon = null; // this icon will be displayed when node is fetching its content this.elementIcon = null; // this icon will be displayed when node is fetching its content this.isCreated = false; // is table structure for this node created. this.isChildrenCreated = false; // is table structure for childnodes created this.isFetching = false; // is node fetching its content at a moment this.data = null; // JSON data for this node this.children = []; // array of child nodes this.labelContainer = null; // reference to label container (top DIV element) this.iconElement = null; // reference to icon element (icons)(TD) this.signElement = null; // reference to sign element (plus/minus)(TD) this.childrenContainer = null; // reference to elements that holds children (DIV) this.checkboxContainer = null; // reference to checkbox element this.oldSource = null; // temp variable that is used for fetch logic this.oldSourceType = null; // temp variable that is used for fetch logic Zapatec.Tree.Node.SUPERclass.init.call(this, config); if(!this.config.isRootNode){ // add reference to Z.Tree#allNodes array this.config.tree.allNodes.push(this); } // load initial data this.loadData(); // clear source (to not load data one more time) this.config.source = null; this.config.sourceType = null; if(!this.config.isRootNode){ // extract source && sourceType from callName if possible. And next time node will be expanded - children nodes will be loaded from this source if(this.data.attributes && this.data.attributes['class']){ var md = null; // Process element's className. If it has zpLoadHTML or zpLoadXML or zpLoadJSON - fill source&&sourceType if(md = this.data.attributes['class'].match(/zpLoad(JSON|HTML|XML)=([^ $]*)/)){ this.data.source = md[2]; if(md[1] == "JSON"){ this.data.sourceType = "json/url"; } else if(md[1] == "HTML"){ this.data.sourceType = "html/url"; } else if(md[1] == "XML"){ this.data.sourceType = "xml/url"; } else { this.data.source = null; this.data.sourceType = null; } } } if(this.data.source){ // if node has source&&sourceType - we must to display +/- sign // if node has zpLoadAlways mark - no predefined children allowed if( this.data.children == null || this.data.loadAlways ){ this.data.children = []; } this.config.source = this.data.source; this.config.sourceType = this.data.sourceType; } }};/** * Adds standard event listeners. */Zapatec.Tree.Node.prototype.addStandardEventListeners = function(){ Zapatec.Tree.Node.SUPERclass.addStandardEventListeners.call(this); // put fetching icon if fetching URL from remote source this.addEventListener('fetchSourceStart', function(){ this.isFetching = true; this.putIcons(); }); // when source is fetched - remove "fetching icon" this.addEventListener("fetchSourceEnd", function(){ this.isFetching = false; this.putIcons(); }); var tmpFunc = function(){ if( this.data && this.data.loadAlways ){ for(var ii = this.children.length - 1; ii >= 0; ii--){ this.children[ii].destroy(true); } this.data.children = []; if(this.childrenContainer){ this.childrenContainer.innerHTML = ""; } } }; this.addEventListener('loadDataStart', tmpFunc); this.addEventListener('fetchSourceStart', tmpFunc); // when data is loaded - process it. this.addEventListener('loadDataEnd', function(){ this.oldSource = this.config.source; this.oldSourceType = this.config.sourceType; this.config.source = null; this.config.sourceType = null; if(!this.config.isRootNode && this.data.isExpanded){ this.expand(); } if( this.data && this.data.loadAlways ){ this.config.source = this.oldSource; this.config.sourceType = this.oldSourceType; } }); // if there was error retrieving source - restore source&&sourceType. So on next node expand Tree will try to fetch source one more time. this.addEventListener("fetchSourceError", function(objError){ if( this.data && this.data.loadAlways ){ this.config.source = this.oldSourceType; this.config.sourceType = this.oldSourceType; } Zapatec.Log({description: "Error happend while retrieving branch content: " + objError.errorCode + " " + objError.errorDescription}); });};/*** Create table structure for this node**/Zapatec.Tree.Node.prototype.create = function(){ // if node is created or no data for this node or this is root node of the tree if(this.isCreated || this.data == null || this.config.isRootNode){ return null; } this.fireEvent("beforeCreate"); var content = []; // main container for this node content.push("<div class='tree-item"); content.push(this.hasSubtree() ? " tree-item-more " : "" ); content.push("'"); this.labelContainerId = "zpTree"+this.config.tree.id+"Node"+this.id+"LabelContainer"; content.push(" id='"); content.push(this.labelContainerId); content.push("'>"); content.push("<table class='tree-table' cellpadding='0' cellspacing='0'><tbody><tr>"); if( this.hasSubtree() ){ // display +/- element content.push("<td id='"); content.push("zpTree"); content.push(this.config.tree.id); content.push("Node"); content.push(this.id); content.push("SignElement"); content.push("'"); content.push(" onclick='Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"onSignClick\")'"); content.push(" ondblclick='Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"onSignDblclick\")'"); content.push(" class='tgb "); content.push(this.data.isExpanded ? "minus" : "plus"); content.push("'>"); content.push("<img src='"); content.push(Zapatec.zapatecPath); content.push("zpempty.gif' class='tgb' alt=''/>"); content.push("</td>"); } if( this.config.tree.config.defaultIcons || ( this.hasSubtree() && ( this.data.collapsedIcon || this.data.expandedIcon || this.data.fetchingIcon ) || !this.hasSubtree() && this.data.elementIcon ) ){ content.push("<td"); content.push(" id='zpTree"); content.push(this.config.tree.id); content.push("Node"); content.push(this.id); content.push("IconElement'"); content.push(" onclick='Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"onIconClick\")'"); content.push(" ondblclick='Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"onIconDblclick\")'"); content.push(" oncontextmenu='return Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"onIconContextMenu\", event)'"); content.push(" onmouseup='return Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"onIconMouseup\", event)'"); content.push(" class='icon "); if(this.config.tree.config.defaultIcons){ content.push(this.config.tree.config.defaultIcons); } content.push("'>"); // if there is icons defined for this node - use them instead of +/- if( this.data.collapsedIcon || this.data.expandedIcon || this.data.fetchingIcon || this.data.elementIcon ){ if(this.hasSubtree()){ if(this.data.expandedIcon){ content.push(this.data.expandedIcon); } if(this.data.collapsedIcon){ content.push(this.data.collapsedIcon); } if(this.data.fetchingIcon){ content.push(this.data.fetchingIcon); } } else { content.push(this.data.elementIcon); } } else { // spacer content.push("<img src='"); content.push(Zapatec.zapatecPath); content.push("zpempty.gif' class='icon' alt=''/>"); } content.push("</td>"); } if(this.config.tree.config.putCheckboxes){ content.push("<td"); content.push(" id='zpTree"); content.push(this.config.tree.id); content.push("Node"); content.push(this.id); content.push("CheckboxElement'"); content.push(" onclick='Zapatec.Widget.callMethod("); content.push(this.id); content.push(", \"checkboxChanged\")'"); content.push(" class='checkboxContainer "); content.push(this.data.isChecked ? "checkboxChecked" : "checkboxUnchecked") content.push("'>"); // spacer content.push("<img src='"); content.push(Zapatec.zapatecPath); content.push("zpempty.gif' class='checkboxContainer' alt=''/>"); content.push("</td>"); } var attributes = Zapatec.Utils.clone(this.data.attributes); // restore attributes. if(!attributes){ attributes = { "id" : "zpTree" + this.config.tree.id + "Node" + this.id + "LabelElement", "onclick" : "Zapatec.Widget.callMethod("+ this.id +", \"onLabelClick\")", "ondblclick" : "Zapatec.Widget.callMethod("+ this.id +", \"onLabelDblclick\")", "oncontextmenu" : "return Zapatec.Widget.callMethod("+ this.id +", \"onLabelContextMenu\", event)", "onmouseup" : "Zapatec.Widget.callMethod("+ this.id +", \"onLabelMouseup\", event)", "class" : "label " + (this.data.children ? "menutitle" : "submenu") }; } else { if(attributes.id == null){ attributes.id = "zpTree" + this.config.tree.id + "Node" + this.id + "LabelElement"; } if(attributes['class'] != null){ attributes['class'] += " label " + (this.data.children ? "menutitle" : "submenu"); } else { attributes['class'] = "label " + (this.data.children ? "menutitle" : "submenu"); } if(attributes.onclick != null){ attributes.onclick = "Zapatec.Widget.callMethod("+ this.id +", \"onLabelClick\");" + this.data.attributes.onclick; } else { attributes.onclick = "Zapatec.Widget.callMethod("+ this.id +", \"onLabelClick\");"; } if(attributes.ondblclick != null){ attributes.ondblclick = "Zapatec.Widget.callMethod("+ this.id +", \"onLabelDblclick\");" + this.data.attributes.ondblclick; } else { attributes.ondblclick = "Zapatec.Widget.callMethod("+ this.id +", \"onLabelDblclick\");"; } if(attributes.oncontextmenu != null){ attributes.oncontextmenu = "return Zapatec.Widget.callMethod("+ this.id +", \"onLabelContextMenu\", event);" + this.data.attributes.oncontextmenu; } else { attributes.oncontextmenu = "return Zapatec.Widget.callMethod("+ this.id +", \"onLabelContextMenu\", event);"; } if(attributes.onmouseup != null){ attributes.onmouseup = "Zapatec.Widget.callMethod("+ this.id +", \"onLabelMouseup\", event);" + this.data.attributes.onmouseup; } else { attributes.onmouseup = "Zapatec.Widget.callMethod("+ this.id +", \"onLabelMouseup\", event);"; } } // create label node content.push("<td"); if(Zapatec.is_ie){ content.push(" unselectable='on'"); } for(var attrName in attributes){ var tmp = attributes[attrName]; if( typeof(tmp) != 'string' ){ tmp += ""; // convert to string
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -