📄 zapatectreepms.js
字号:
/**
* The Zapatec DHTML Calendar
*
* Copyright (c) 2004-2005 by Zapatec, Inc.
* http://www.zapatec.com
* 1700 MLK Way, Berkeley, California,
* 94709, U.S.A.
* All rights reserved.
*
*
* Tree Widget
*/
// if (_zapatec_tree_url)
// _zapatec_tree_url = _zapatec_tree_url.replace(/\/*$/, '/');
/**
* The Zapatec.Tree object constructor. Pass to it the ID of an UL element (or
* a reference to the element should you have it already) and an optional
* configuration object. This function creates and initializes the tree widget
* according to data existent in the nested list, and applies the configuration
* specified.
*
* The configuration object may contain the following options (the following
* shows default values):
*
* \code
* {
* hiliteSelectedNode : true, // boolean
* compact : false, // boolean
* dynamic : false, // boolean
* initLevel : false, // false or number
* defaultIcons : null // null or string
* }
* \endcode
*
* - hiliteSelectedNode -- if \b false is passed, the tree will not highlight
* the currently selected node.
* - compact -- if \b true is passed the tree will work in a "compact" mode; in
* this mode it automatically closes sections not relevant to the current
* one.
* - dynamic -- if \b true is passed the tree will use the "dynamic initialization"
* technique which greatly improves generation time. Some functionality is
* not available in this mode until all the tree was generated. In "dynamic"
* mode the tree is initially collapsed and levels are generated "on the fly"
* as the end user expands them. You can't retrieve nodes by ID (which
* implies you can't synchronize to certain nodes) until they have been
* generated.
* - initLevel -- when this is a numeric value, it specifies the maximum
* "expand level" that the tree will use initially. Therefore, if for
* instance you specify 1 then the tree will be initially expanded one level.
* Pass here 0 to have the tree fully collapsed, or leave it \b false to have
* the tree fully expanded.
* - defaultIcons -- you can pass here a string. If so, all tree items will
* get an additional TD element containing that string in the \b class
* attribute. This helps you to include custom default icons without
* specifying them as IMG tags in the tree. See our examples.
*
* @param el [string or HTMLElement] -- the UL element
* @param config [Object, optional] -- the configuration options
*
* @return
*/
Zapatec.Tree = function(el, config) {
if (typeof config == "undefined")
config = {};
function param_default(name, value) {
if (typeof config[name] == "undefined")
config[name] = value;
};
param_default('d_profile', false);
param_default('hiliteSelectedNode', false);
param_default('compact', true);
param_default('dynamic', false);
param_default('initLevel', false);
if (config.dynamic)
config.initLevel = 0;
this.config = config;
// <PROFILE>
if (this.config.d_profile) {
var T1 = new Date().getTime();
profile = {
items : 0,
trees : 0,
icons : 0
};
}
// </PROFILE>
if (typeof el == "string")
el = document.getElementById(el);
this.list = el;
this.items = {};
this.trees = {};
this.selectedItem = null;
this.id = el.id || Zapatec.Utils.generateID("tree");
var top = this.top_parent = Zapatec.Utils.createElement("div");
top.className = "tree tree-top";
this.createTree(el, top, 0);
el.parentNode.insertBefore(top, el);
el.parentNode.removeChild(el);
Zapatec.Tree.all[this.id] = this;
// check if we have an initially selected node and sync. the tree if so
if (this.selectedItem)
this.sync(this.selectedItem.__msh_item);
// <PROFILE>
if (this.config.d_profile) {
alert("Generated in " + (new Date().getTime() - T1) + " milliseconds\n" +
profile.items + " total tree items\n" +
profile.trees + " total (sub)trees\n" +
profile.icons + " total icons");
}
// </PROFILE>
};
/**
* This global variable keeps a "hash table" (that is, a plain JavaScript
* object) mapping ID-s to references to Zapatec.Tree objects. It's helpful if
* you want to operate on a tree but you don't want to keep a reference to it.
* Example:
*
* \code
* // the following makes a tree for the <ul id="tree-id"> element
* var tree = new Zapatec.Tree("tree-id");
* // ... later
* var existing_tree = Zapatec.Tree.all("tree-id");
* // and now we can use \b existing_tree the same as we can use \b tree
* // the following displays \b true
* alert(existing_tree == tree);
* \endcode
*
* So in short, this variable remembers values returned by "new
* Zapatec.Tree(...)" in case you didn't.
*/
Zapatec.Tree.all = {};
/**
* \internal Function that creates a (sub)tree. This function walks the UL
* element, computes and assigns CSS class names and creates HTML elements for
* a subtree. Each time a LI element is encountered, createItem() is called
* which effectively creates the item. Beware that createItem() might call
* back this function in order to create the item's subtree. (so createTree and
* createItem form an indirect recursion).
*
* @param list [HTMLElement] -- reference to the UL element
* @param parent [HTMLElement] -- reference to the parent element that should hold the (sub)tree
* @param level [integer] -- the level of this (sub)tree in the main tree.
*
* @return id -- the (sub)tree ID; might be automatically generated.
*/
Zapatec.Tree.prototype.createTree = function(list, parent, level) {
if (this.config.d_profile) // PROFILE
++profile.trees; // PROFILE
var id = list.id || Zapatec.Utils.generateID("tree.sub"),
self = this;
function _makeIt() {
self.creating_now = true;
var
last_li = null,
next_li,
i = list.firstChild,
items = parent.__msh_items = [];
self.trees[id] = parent;
parent.__msh_level = level;
parent.__msh_treeid = id;
while (i) {
if (last_li)
last_li.className += " tree-lines-c";
if (i.nodeType != 1)
i = i.nextSibling;
else {
next_li = Zapatec.Utils.getNextSibling(i, 'li');
if (i.tagName.toLowerCase() == 'li') {
last_li = self.createItem(i, parent, next_li, level);
if (last_li) { //false when webmaster creates malformed tree
items[items.length] = last_li.__msh_item;
}
}
i = next_li;
}
}
i = parent.firstChild;
if (i && !level) {
i.className = i.className.replace(/ tree-lines-./g, "");
i.className += (i === last_li) ? " tree-lines-s" : " tree-lines-t";
}
if (last_li && (level || last_li !== i)) {
last_li.className = last_li.className.replace(/ tree-lines-./g, "");
last_li.className += " tree-lines-b";
}
self.creating_now = false;
};
if (this.config.dynamic && level > 0)
this.trees[id] = _makeIt;
else
_makeIt();
return id;
};
/**
* \internal This function walks through a LI element and creates the HTML
* elements associated with that tree item. When it encounters an UL element
* it calls createTree() in order to create the item's subtree. This function
* may also call item_addIcon() in order to add the +/- buttons or icons
* present in the item definition as IMG tags, or item_addDefaultIcon() if the
* tree configuration specifies "defaultIcons" and no IMG tag was present.
*
* @param li [HTMLElement] -- reference to the LI element
* @param parent [HTMLElement] -- reference to the parent element where the HTML elements should be created
* @param next_li [HTMLLiElement] -- reference to the next LI element, if this is not the last one
* @param level [integer] -- the level of this item in the main tree
*
* @return [HTMLElement] -- a reference to a DIV element holding the HTML elements of the created item
*/
Zapatec.Tree.prototype.createItem = function(li, parent, next_li, level) {
if (this.config.d_profile) // PROFILE
++profile.items; // PROFILE
if (!li.firstChild)
return;
var
id = li.id || Zapatec.Utils.generateID("tree.item"),
item = this.items[id] = Zapatec.Utils.createElement("div", parent),
t = Zapatec.Utils.createElement("table", item),
tb = Zapatec.Utils.createElement("tbody", t),
tr = Zapatec.Utils.createElement("tr", tb),
td = Zapatec.Utils.createElement("td", tr),
is_list,
tmp,
i = li.firstChild,
has_icon = false;
t.className = "tree-table";
t.cellSpacing = 0;
t.cellPadding = 0;
td.className = "label";
item.className = "tree-item";
item.__msh_item = id;
item.__msh_tree = this.id;
item.__msh_parent = parent.__msh_treeid;
//add wanglj
item._id=li.id;
item._code=li.codeId ;
item._pid=li.codeSuperId;
item._treeId=li.treeId;
item._name=li.name;
item._abbr=li.abbr;
item._spell=li.spell;
item._status=li.status;
item._layer=li.layer ;
item._pNode=li.pNode ;
//end
while (i) {
is_list = i.nodeType == 1 && /^[ou]l$/i.test(i.tagName);
if (i.nodeType != 1 || !is_list) {
if (i.nodeType == 3) {
// remove whitespace, it seems to cause layout trouble
tmp = i.data.replace(/^\s+/, '');
tmp = tmp.replace(/\s+$/, '');
li.removeChild(i);
if (tmp) {
i = Zapatec.Utils.createElement("span");
i.className = "label";
i.innerHTML = tmp;
i.onclick = Zapatec.Tree.onItemToggle;
td.appendChild(i);
}
} else if (i.tagName.toLowerCase() == 'img') {
this.item_addIcon(item, i);
has_icon = true;
} else {
i.onclick = Zapatec.Tree.onItemToggle;
td.appendChild(i);
}
i = li.firstChild;
continue;
}
if (is_list) {
this.item_addIcon(item, null);
var np = Zapatec.Utils.createElement("div", item.parentNode);
np.__msh_item = id;
np.className = "tree";
if (next_li)
np.className += " tree-lined";
item.__msh_subtree = this.createTree(i, np, level+1);
if ((this.config.initLevel !== false && this.config.initLevel <= level) ||
(this.config.compact && !/(^|\s)expanded(\s|$)/i.test(li.className))
|| /(^|\s)collapsed(\s|$)/i.test(li.className)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -