cl
2024-05-23 ba1a7a9ef126296e2798e313dc5b43f775a1123c
提交 | 用户 | 时间
71e81e 1 /*
2  * JQuery zTree core v3.5.40
3  * http://treejs.cn/
4  *
5  * Copyright (c) 2010 Hunter.z
6  *
7  * Licensed same as jquery - MIT License
8  * http://www.opensource.org/licenses/mit-license.php
9  *
10  * email: hunter.z@263.net
11  * Date: 2019-01-18
12  */
13 layui.define(['jquery'], function (exports) {
14     var $ = layui.jquery;
15     var jQuery = layui.$;
16     layui.link(layui.cache.base + 'zTree/css/zTreeStyle/zTreeStyle.css');  // 默认风格
17     // layui.link(layui.cache.base + 'zTree/css/metroStyle/metroStyle.css');  // 扁平化风格
18
19     (function ($) {
20         var settings = {}, roots = {}, caches = {},
21             //default consts of core
22             _consts = {
23                 className: {
24                     BUTTON: "button",
25                     LEVEL: "level",
26                     ICO_LOADING: "ico_loading",
27                     SWITCH: "switch",
28                     NAME: 'node_name'
29                 },
30                 event: {
31                     NODECREATED: "ztree_nodeCreated",
32                     CLICK: "ztree_click",
33                     EXPAND: "ztree_expand",
34                     COLLAPSE: "ztree_collapse",
35                     ASYNC_SUCCESS: "ztree_async_success",
36                     ASYNC_ERROR: "ztree_async_error",
37                     REMOVE: "ztree_remove",
38                     SELECTED: "ztree_selected",
39                     UNSELECTED: "ztree_unselected"
40                 },
41                 id: {
42                     A: "_a",
43                     ICON: "_ico",
44                     SPAN: "_span",
45                     SWITCH: "_switch",
46                     UL: "_ul"
47                 },
48                 line: {
49                     ROOT: "root",
50                     ROOTS: "roots",
51                     CENTER: "center",
52                     BOTTOM: "bottom",
53                     NOLINE: "noline",
54                     LINE: "line"
55                 },
56                 folder: {
57                     OPEN: "open",
58                     CLOSE: "close",
59                     DOCU: "docu"
60                 },
61                 node: {
62                     CURSELECTED: "curSelectedNode"
63                 }
64             },
65             //default setting of core
66             _setting = {
67                 treeId: "",
68                 treeObj: null,
69                 view: {
70                     addDiyDom: null,
71                     autoCancelSelected: true,
72                     dblClickExpand: true,
73                     expandSpeed: "fast",
74                     fontCss: {},
75                     nameIsHTML: false,
76                     selectedMulti: true,
77                     showIcon: true,
78                     showLine: true,
79                     showTitle: true,
80                     txtSelectedEnable: false
81                 },
82                 data: {
83                     key: {
84                         isParent: "isParent",
85                         children: "children",
86                         name: "name",
87                         title: "",
88                         url: "url",
89                         icon: "icon"
90                     },
91                     simpleData: {
92                         enable: false,
93                         idKey: "id",
94                         pIdKey: "pId",
95                         rootPId: null
96                     },
97                     keep: {
98                         parent: false,
99                         leaf: false
100                     }
101                 },
102                 async: {
103                     enable: false,
104                     contentType: "application/x-www-form-urlencoded",
105                     type: "post",
106                     dataType: "text",
107                     headers: {},
108                     xhrFields: {},
109                     url: "",
110                     autoParam: [],
111                     otherParam: [],
112                     dataFilter: null
113                 },
114                 callback: {
115                     beforeAsync: null,
116                     beforeClick: null,
117                     beforeDblClick: null,
118                     beforeRightClick: null,
119                     beforeMouseDown: null,
120                     beforeMouseUp: null,
121                     beforeExpand: null,
122                     beforeCollapse: null,
123                     beforeRemove: null,
124
125                     onAsyncError: null,
126                     onAsyncSuccess: null,
127                     onNodeCreated: null,
128                     onClick: null,
129                     onDblClick: null,
130                     onRightClick: null,
131                     onMouseDown: null,
132                     onMouseUp: null,
133                     onExpand: null,
134                     onCollapse: null,
135                     onRemove: null
136                 }
137             },
138             //default root of core
139             //zTree use root to save full data
140             _initRoot = function (setting) {
141                 var r = data.getRoot(setting);
142                 if (!r) {
143                     r = {};
144                     data.setRoot(setting, r);
145                 }
146                 data.nodeChildren(setting, r, []);
147                 r.expandTriggerFlag = false;
148                 r.curSelectedList = [];
149                 r.noSelection = true;
150                 r.createdNodes = [];
151                 r.zId = 0;
152                 r._ver = (new Date()).getTime();
153             },
154             //default cache of core
155             _initCache = function (setting) {
156                 var c = data.getCache(setting);
157                 if (!c) {
158                     c = {};
159                     data.setCache(setting, c);
160                 }
161                 c.nodes = [];
162                 c.doms = [];
163             },
164             //default bindEvent of core
165             _bindEvent = function (setting) {
166                 var o = setting.treeObj,
167                     c = consts.event;
168                 o.bind(c.NODECREATED, function (event, treeId, node) {
169                     tools.apply(setting.callback.onNodeCreated, [event, treeId, node]);
170                 });
171
172                 o.bind(c.CLICK, function (event, srcEvent, treeId, node, clickFlag) {
173                     tools.apply(setting.callback.onClick, [srcEvent, treeId, node, clickFlag]);
174                 });
175
176                 o.bind(c.EXPAND, function (event, treeId, node) {
177                     tools.apply(setting.callback.onExpand, [event, treeId, node]);
178                 });
179
180                 o.bind(c.COLLAPSE, function (event, treeId, node) {
181                     tools.apply(setting.callback.onCollapse, [event, treeId, node]);
182                 });
183
184                 o.bind(c.ASYNC_SUCCESS, function (event, treeId, node, msg) {
185                     tools.apply(setting.callback.onAsyncSuccess, [event, treeId, node, msg]);
186                 });
187
188                 o.bind(c.ASYNC_ERROR, function (event, treeId, node, XMLHttpRequest, textStatus, errorThrown) {
189                     tools.apply(setting.callback.onAsyncError, [event, treeId, node, XMLHttpRequest, textStatus, errorThrown]);
190                 });
191
192                 o.bind(c.REMOVE, function (event, treeId, treeNode) {
193                     tools.apply(setting.callback.onRemove, [event, treeId, treeNode]);
194                 });
195
196                 o.bind(c.SELECTED, function (event, treeId, node) {
197                     tools.apply(setting.callback.onSelected, [treeId, node]);
198                 });
199                 o.bind(c.UNSELECTED, function (event, treeId, node) {
200                     tools.apply(setting.callback.onUnSelected, [treeId, node]);
201                 });
202             },
203             _unbindEvent = function (setting) {
204                 var o = setting.treeObj,
205                     c = consts.event;
206                 o.unbind(c.NODECREATED)
207                     .unbind(c.CLICK)
208                     .unbind(c.EXPAND)
209                     .unbind(c.COLLAPSE)
210                     .unbind(c.ASYNC_SUCCESS)
211                     .unbind(c.ASYNC_ERROR)
212                     .unbind(c.REMOVE)
213                     .unbind(c.SELECTED)
214                     .unbind(c.UNSELECTED);
215             },
216             //default event proxy of core
217             _eventProxy = function (event) {
218                 var target = event.target,
219                     setting = data.getSetting(event.data.treeId),
220                     tId = "", node = null,
221                     nodeEventType = "", treeEventType = "",
222                     nodeEventCallback = null, treeEventCallback = null,
223                     tmp = null;
224
225                 if (tools.eqs(event.type, "mousedown")) {
226                     treeEventType = "mousedown";
227                 } else if (tools.eqs(event.type, "mouseup")) {
228                     treeEventType = "mouseup";
229                 } else if (tools.eqs(event.type, "contextmenu")) {
230                     treeEventType = "contextmenu";
231                 } else if (tools.eqs(event.type, "click")) {
232                     if (tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.SWITCH) !== null) {
233                         tId = tools.getNodeMainDom(target).id;
234                         nodeEventType = "switchNode";
235                     } else {
236                         tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]);
237                         if (tmp) {
238                             tId = tools.getNodeMainDom(tmp).id;
239                             nodeEventType = "clickNode";
240                         }
241                     }
242                 } else if (tools.eqs(event.type, "dblclick")) {
243                     treeEventType = "dblclick";
244                     tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]);
245                     if (tmp) {
246                         tId = tools.getNodeMainDom(tmp).id;
247                         nodeEventType = "switchNode";
248                     }
249                 }
250                 if (treeEventType.length > 0 && tId.length == 0) {
251                     tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]);
252                     if (tmp) {
253                         tId = tools.getNodeMainDom(tmp).id;
254                     }
255                 }
256                 // event to node
257                 if (tId.length > 0) {
258                     node = data.getNodeCache(setting, tId);
259                     switch (nodeEventType) {
260                         case "switchNode" :
261                             var isParent = data.nodeIsParent(setting, node);
262                             if (!isParent) {
263                                 nodeEventType = "";
264                             } else if (tools.eqs(event.type, "click")
265                                 || (tools.eqs(event.type, "dblclick") && tools.apply(setting.view.dblClickExpand, [setting.treeId, node], setting.view.dblClickExpand))) {
266                                 nodeEventCallback = handler.onSwitchNode;
267                             } else {
268                                 nodeEventType = "";
269                             }
270                             break;
271                         case "clickNode" :
272                             nodeEventCallback = handler.onClickNode;
273                             break;
274                     }
275                 }
276                 // event to zTree
277                 switch (treeEventType) {
278                     case "mousedown" :
279                         treeEventCallback = handler.onZTreeMousedown;
280                         break;
281                     case "mouseup" :
282                         treeEventCallback = handler.onZTreeMouseup;
283                         break;
284                     case "dblclick" :
285                         treeEventCallback = handler.onZTreeDblclick;
286                         break;
287                     case "contextmenu" :
288                         treeEventCallback = handler.onZTreeContextmenu;
289                         break;
290                 }
291                 var proxyResult = {
292                     stop: false,
293                     node: node,
294                     nodeEventType: nodeEventType,
295                     nodeEventCallback: nodeEventCallback,
296                     treeEventType: treeEventType,
297                     treeEventCallback: treeEventCallback
298                 };
299                 return proxyResult
300             },
301             //default init node of core
302             _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) {
303                 if (!n) return;
304                 var r = data.getRoot(setting),
305                     children = data.nodeChildren(setting, n);
306                 n.level = level;
307                 n.tId = setting.treeId + "_" + (++r.zId);
308                 n.parentTId = parentNode ? parentNode.tId : null;
309                 n.open = (typeof n.open == "string") ? tools.eqs(n.open, "true") : !!n.open;
310                 var isParent = data.nodeIsParent(setting, n);
311                 if (tools.isArray(children)) {
312                     data.nodeIsParent(setting, n, true);
313                     n.zAsync = true;
314                 } else {
315                     isParent = data.nodeIsParent(setting, n, isParent);
316                     n.open = (isParent && !setting.async.enable) ? n.open : false;
317                     n.zAsync = !isParent;
318                 }
319                 n.isFirstNode = isFirstNode;
320                 n.isLastNode = isLastNode;
321                 n.getParentNode = function () {
322                     return data.getNodeCache(setting, n.parentTId);
323                 };
324                 n.getPreNode = function () {
325                     return data.getPreNode(setting, n);
326                 };
327                 n.getNextNode = function () {
328                     return data.getNextNode(setting, n);
329                 };
330                 n.getIndex = function () {
331                     return data.getNodeIndex(setting, n);
332                 };
333                 n.getPath = function () {
334                     return data.getNodePath(setting, n);
335                 };
336                 n.isAjaxing = false;
337                 data.fixPIdKeyValue(setting, n);
338             },
339             _init = {
340                 bind: [_bindEvent],
341                 unbind: [_unbindEvent],
342                 caches: [_initCache],
343                 nodes: [_initNode],
344                 proxys: [_eventProxy],
345                 roots: [_initRoot],
346                 beforeA: [],
347                 afterA: [],
348                 innerBeforeA: [],
349                 innerAfterA: [],
350                 zTreeTools: []
351             },
352             //method of operate data
353             data = {
354                 addNodeCache: function (setting, node) {
355                     data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = node;
356                 },
357                 getNodeCacheId: function (tId) {
358                     return tId.substring(tId.lastIndexOf("_") + 1);
359                 },
360                 addAfterA: function (afterA) {
361                     _init.afterA.push(afterA);
362                 },
363                 addBeforeA: function (beforeA) {
364                     _init.beforeA.push(beforeA);
365                 },
366                 addInnerAfterA: function (innerAfterA) {
367                     _init.innerAfterA.push(innerAfterA);
368                 },
369                 addInnerBeforeA: function (innerBeforeA) {
370                     _init.innerBeforeA.push(innerBeforeA);
371                 },
372                 addInitBind: function (bindEvent) {
373                     _init.bind.push(bindEvent);
374                 },
375                 addInitUnBind: function (unbindEvent) {
376                     _init.unbind.push(unbindEvent);
377                 },
378                 addInitCache: function (initCache) {
379                     _init.caches.push(initCache);
380                 },
381                 addInitNode: function (initNode) {
382                     _init.nodes.push(initNode);
383                 },
384                 addInitProxy: function (initProxy, isFirst) {
385                     if (!!isFirst) {
386                         _init.proxys.splice(0, 0, initProxy);
387                     } else {
388                         _init.proxys.push(initProxy);
389                     }
390                 },
391                 addInitRoot: function (initRoot) {
392                     _init.roots.push(initRoot);
393                 },
394                 addNodesData: function (setting, parentNode, index, nodes) {
395                     var children = data.nodeChildren(setting, parentNode), params;
396                     if (!children) {
397                         children = data.nodeChildren(setting, parentNode, []);
398                         index = -1;
399                     } else if (index >= children.length) {
400                         index = -1;
401                     }
402
403                     if (children.length > 0 && index === 0) {
404                         children[0].isFirstNode = false;
405                         view.setNodeLineIcos(setting, children[0]);
406                     } else if (children.length > 0 && index < 0) {
407                         children[children.length - 1].isLastNode = false;
408                         view.setNodeLineIcos(setting, children[children.length - 1]);
409                     }
410                     data.nodeIsParent(setting, parentNode, true);
411
412                     if (index < 0) {
413                         data.nodeChildren(setting, parentNode, children.concat(nodes));
414                     } else {
415                         params = [index, 0].concat(nodes);
416                         children.splice.apply(children, params);
417                     }
418                 },
419                 addSelectedNode: function (setting, node) {
420                     var root = data.getRoot(setting);
421                     if (!data.isSelectedNode(setting, node)) {
422                         root.curSelectedList.push(node);
423                     }
424                 },
425                 addCreatedNode: function (setting, node) {
426                     if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) {
427                         var root = data.getRoot(setting);
428                         root.createdNodes.push(node);
429                     }
430                 },
431                 addZTreeTools: function (zTreeTools) {
432                     _init.zTreeTools.push(zTreeTools);
433                 },
434                 exSetting: function (s) {
435                     $.extend(true, _setting, s);
436                 },
437                 fixPIdKeyValue: function (setting, node) {
438                     if (setting.data.simpleData.enable) {
439                         node[setting.data.simpleData.pIdKey] = node.parentTId ? node.getParentNode()[setting.data.simpleData.idKey] : setting.data.simpleData.rootPId;
440                     }
441                 },
442                 getAfterA: function (setting, node, array) {
443                     for (var i = 0, j = _init.afterA.length; i < j; i++) {
444                         _init.afterA[i].apply(this, arguments);
445                     }
446                 },
447                 getBeforeA: function (setting, node, array) {
448                     for (var i = 0, j = _init.beforeA.length; i < j; i++) {
449                         _init.beforeA[i].apply(this, arguments);
450                     }
451                 },
452                 getInnerAfterA: function (setting, node, array) {
453                     for (var i = 0, j = _init.innerAfterA.length; i < j; i++) {
454                         _init.innerAfterA[i].apply(this, arguments);
455                     }
456                 },
457                 getInnerBeforeA: function (setting, node, array) {
458                     for (var i = 0, j = _init.innerBeforeA.length; i < j; i++) {
459                         _init.innerBeforeA[i].apply(this, arguments);
460                     }
461                 },
462                 getCache: function (setting) {
463                     return caches[setting.treeId];
464                 },
465                 getNodeIndex: function (setting, node) {
466                     if (!node) return null;
467                     var p = node.parentTId ? node.getParentNode() : data.getRoot(setting),
468                         children = data.nodeChildren(setting, p);
469                     for (var i = 0, l = children.length - 1; i <= l; i++) {
470                         if (children[i] === node) {
471                             return i;
472                         }
473                     }
474                     return -1;
475                 },
476                 getNextNode: function (setting, node) {
477                     if (!node) return null;
478                     var p = node.parentTId ? node.getParentNode() : data.getRoot(setting),
479                         children = data.nodeChildren(setting, p);
480                     for (var i = 0, l = children.length - 1; i <= l; i++) {
481                         if (children[i] === node) {
482                             return (i == l ? null : children[i + 1]);
483                         }
484                     }
485                     return null;
486                 },
487                 getNodeByParam: function (setting, nodes, key, value) {
488                     if (!nodes || !key) return null;
489                     for (var i = 0, l = nodes.length; i < l; i++) {
490                         var node = nodes[i];
491                         if (node[key] == value) {
492                             return nodes[i];
493                         }
494                         var children = data.nodeChildren(setting, node);
495                         var tmp = data.getNodeByParam(setting, children, key, value);
496                         if (tmp) return tmp;
497                     }
498                     return null;
499                 },
500                 getNodeCache: function (setting, tId) {
501                     if (!tId) return null;
502                     var n = caches[setting.treeId].nodes[data.getNodeCacheId(tId)];
503                     return n ? n : null;
504                 },
505                 getNodePath: function (setting, node) {
506                     if (!node) return null;
507
508                     var path;
509                     if (node.parentTId) {
510                         path = node.getParentNode().getPath();
511                     } else {
512                         path = [];
513                     }
514
515                     if (path) {
516                         path.push(node);
517                     }
518
519                     return path;
520                 },
521                 getNodes: function (setting) {
522                     return data.nodeChildren(setting, data.getRoot(setting));
523                 },
524                 getNodesByParam: function (setting, nodes, key, value) {
525                     if (!nodes || !key) return [];
526                     var result = [];
527                     for (var i = 0, l = nodes.length; i < l; i++) {
528                         var node = nodes[i];
529                         if (node[key] == value) {
530                             result.push(node);
531                         }
532                         var children = data.nodeChildren(setting, node);
533                         result = result.concat(data.getNodesByParam(setting, children, key, value));
534                     }
535                     return result;
536                 },
537                 getNodesByParamFuzzy: function (setting, nodes, key, value) {
538                     if (!nodes || !key) return [];
539                     var result = [];
540                     value = value.toLowerCase();
541                     for (var i = 0, l = nodes.length; i < l; i++) {
542                         var node = nodes[i];
543                         if (typeof node[key] == "string" && nodes[i][key].toLowerCase().indexOf(value) > -1) {
544                             result.push(node);
545                         }
546                         var children = data.nodeChildren(setting, node);
547                         result = result.concat(data.getNodesByParamFuzzy(setting, children, key, value));
548                     }
549                     return result;
550                 },
551                 getNodesByFilter: function (setting, nodes, filter, isSingle, invokeParam) {
552                     if (!nodes) return (isSingle ? null : []);
553                     var result = isSingle ? null : [];
554                     for (var i = 0, l = nodes.length; i < l; i++) {
555                         var node = nodes[i];
556                         if (tools.apply(filter, [node, invokeParam], false)) {
557                             if (isSingle) {
558                                 return node;
559                             }
560                             result.push(node);
561                         }
562                         var children = data.nodeChildren(setting, node);
563                         var tmpResult = data.getNodesByFilter(setting, children, filter, isSingle, invokeParam);
564                         if (isSingle && !!tmpResult) {
565                             return tmpResult;
566                         }
567                         result = isSingle ? tmpResult : result.concat(tmpResult);
568                     }
569                     return result;
570                 },
571                 getPreNode: function (setting, node) {
572                     if (!node) return null;
573                     var p = node.parentTId ? node.getParentNode() : data.getRoot(setting),
574                         children = data.nodeChildren(setting, p);
575                     for (var i = 0, l = children.length; i < l; i++) {
576                         if (children[i] === node) {
577                             return (i == 0 ? null : children[i - 1]);
578                         }
579                     }
580                     return null;
581                 },
582                 getRoot: function (setting) {
583                     return setting ? roots[setting.treeId] : null;
584                 },
585                 getRoots: function () {
586                     return roots;
587                 },
588                 getSetting: function (treeId) {
589                     return settings[treeId];
590                 },
591                 getSettings: function () {
592                     return settings;
593                 },
594                 getZTreeTools: function (treeId) {
595                     var r = this.getRoot(this.getSetting(treeId));
596                     return r ? r.treeTools : null;
597                 },
598                 initCache: function (setting) {
599                     for (var i = 0, j = _init.caches.length; i < j; i++) {
600                         _init.caches[i].apply(this, arguments);
601                     }
602                 },
603                 initNode: function (setting, level, node, parentNode, preNode, nextNode) {
604                     for (var i = 0, j = _init.nodes.length; i < j; i++) {
605                         _init.nodes[i].apply(this, arguments);
606                     }
607                 },
608                 initRoot: function (setting) {
609                     for (var i = 0, j = _init.roots.length; i < j; i++) {
610                         _init.roots[i].apply(this, arguments);
611                     }
612                 },
613                 isSelectedNode: function (setting, node) {
614                     var root = data.getRoot(setting);
615                     for (var i = 0, j = root.curSelectedList.length; i < j; i++) {
616                         if (node === root.curSelectedList[i]) return true;
617                     }
618                     return false;
619                 },
620                 nodeChildren: function (setting, node, newChildren) {
621                     if (!node) {
622                         return null;
623                     }
624                     var key = setting.data.key.children;
625                     if (typeof newChildren !== 'undefined') {
626                         node[key] = newChildren;
627                     }
628                     return node[key];
629                 },
630                 nodeIsParent: function (setting, node, newIsParent) {
631                     if (!node) {
632                         return false;
633                     }
634                     var key = setting.data.key.isParent;
635                     if (typeof newIsParent !== 'undefined') {
636                         if (typeof newIsParent === "string") {
637                             newIsParent = tools.eqs(newIsParent, "true");
638                         }
639                         newIsParent = !!newIsParent;
640                         node[key] = newIsParent;
641                     } else if (typeof node[key] == "string") {
642                         node[key] = tools.eqs(node[key], "true");
643                     } else {
644                         node[key] = !!node[key];
645                     }
646                     return node[key];
647                 },
648                 nodeName: function (setting, node, newName) {
649                     var key = setting.data.key.name;
650                     if (typeof newName !== 'undefined') {
651                         node[key] = newName;
652                     }
653                     return "" + node[key];
654                 },
655                 nodeTitle: function (setting, node) {
656                     var t = setting.data.key.title === "" ? setting.data.key.name : setting.data.key.title;
657                     return "" + node[t];
658                 },
659                 removeNodeCache: function (setting, node) {
660                     var children = data.nodeChildren(setting, node);
661                     if (children) {
662                         for (var i = 0, l = children.length; i < l; i++) {
663                             data.removeNodeCache(setting, children[i]);
664                         }
665                     }
666                     data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = null;
667                 },
668                 removeSelectedNode: function (setting, node) {
669                     var root = data.getRoot(setting);
670                     for (var i = 0, j = root.curSelectedList.length; i < j; i++) {
671                         if (node === root.curSelectedList[i] || !data.getNodeCache(setting, root.curSelectedList[i].tId)) {
672                             root.curSelectedList.splice(i, 1);
673                             setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, node]);
674                             i--;
675                             j--;
676                         }
677                     }
678                 },
679                 setCache: function (setting, cache) {
680                     caches[setting.treeId] = cache;
681                 },
682                 setRoot: function (setting, root) {
683                     roots[setting.treeId] = root;
684                 },
685                 setZTreeTools: function (setting, zTreeTools) {
686                     for (var i = 0, j = _init.zTreeTools.length; i < j; i++) {
687                         _init.zTreeTools[i].apply(this, arguments);
688                     }
689                 },
690                 transformToArrayFormat: function (setting, nodes) {
691                     if (!nodes) return [];
692                     var r = [];
693                     if (tools.isArray(nodes)) {
694                         for (var i = 0, l = nodes.length; i < l; i++) {
695                             var node = nodes[i];
696                             _do(node);
697                         }
698                     } else {
699                         _do(nodes);
700                     }
701                     return r;
702
703                     function _do(_node) {
704                         r.push(_node);
705                         var children = data.nodeChildren(setting, _node);
706                         if (children) {
707                             r = r.concat(data.transformToArrayFormat(setting, children));
708                         }
709                     }
710                 },
711                 transformTozTreeFormat: function (setting, sNodes) {
712                     var i, l,
713                         key = setting.data.simpleData.idKey,
714                         parentKey = setting.data.simpleData.pIdKey;
715                     if (!key || key == "" || !sNodes) return [];
716
717                     if (tools.isArray(sNodes)) {
718                         var r = [];
719                         var tmpMap = {};
720                         for (i = 0, l = sNodes.length; i < l; i++) {
721                             tmpMap[sNodes[i][key]] = sNodes[i];
722                         }
723                         for (i = 0, l = sNodes.length; i < l; i++) {
724                             var p = tmpMap[sNodes[i][parentKey]];
725                             if (p && sNodes[i][key] != sNodes[i][parentKey]) {
726                                 var children = data.nodeChildren(setting, p);
727                                 if (!children) {
728                                     children = data.nodeChildren(setting, p, []);
729                                 }
730                                 children.push(sNodes[i]);
731                             } else {
732                                 r.push(sNodes[i]);
733                             }
734                         }
735                         return r;
736                     } else {
737                         return [sNodes];
738                     }
739                 }
740             },
741             //method of event proxy
742             event = {
743                 bindEvent: function (setting) {
744                     for (var i = 0, j = _init.bind.length; i < j; i++) {
745                         _init.bind[i].apply(this, arguments);
746                     }
747                 },
748                 unbindEvent: function (setting) {
749                     for (var i = 0, j = _init.unbind.length; i < j; i++) {
750                         _init.unbind[i].apply(this, arguments);
751                     }
752                 },
753                 bindTree: function (setting) {
754                     var eventParam = {
755                             treeId: setting.treeId
756                         },
757                         o = setting.treeObj;
758                     if (!setting.view.txtSelectedEnable) {
759                         // for can't select text
760                         o.bind('selectstart', handler.onSelectStart).css({
761                             "-moz-user-select": "-moz-none"
762                         });
763                     }
764                     o.bind('click', eventParam, event.proxy);
765                     o.bind('dblclick', eventParam, event.proxy);
766                     o.bind('mouseover', eventParam, event.proxy);
767                     o.bind('mouseout', eventParam, event.proxy);
768                     o.bind('mousedown', eventParam, event.proxy);
769                     o.bind('mouseup', eventParam, event.proxy);
770                     o.bind('contextmenu', eventParam, event.proxy);
771                 },
772                 unbindTree: function (setting) {
773                     var o = setting.treeObj;
774                     o.unbind('selectstart', handler.onSelectStart)
775                         .unbind('click', event.proxy)
776                         .unbind('dblclick', event.proxy)
777                         .unbind('mouseover', event.proxy)
778                         .unbind('mouseout', event.proxy)
779                         .unbind('mousedown', event.proxy)
780                         .unbind('mouseup', event.proxy)
781                         .unbind('contextmenu', event.proxy);
782                 },
783                 doProxy: function (e) {
784                     var results = [];
785                     for (var i = 0, j = _init.proxys.length; i < j; i++) {
786                         var proxyResult = _init.proxys[i].apply(this, arguments);
787                         results.push(proxyResult);
788                         if (proxyResult.stop) {
789                             break;
790                         }
791                     }
792                     return results;
793                 },
794                 proxy: function (e) {
795                     var setting = data.getSetting(e.data.treeId);
796                     if (!tools.uCanDo(setting, e)) return true;
797                     var results = event.doProxy(e),
798                         r = true, x = false;
799                     for (var i = 0, l = results.length; i < l; i++) {
800                         var proxyResult = results[i];
801                         if (proxyResult.nodeEventCallback) {
802                             x = true;
803                             r = proxyResult.nodeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r;
804                         }
805                         if (proxyResult.treeEventCallback) {
806                             x = true;
807                             r = proxyResult.treeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r;
808                         }
809                     }
810                     return r;
811                 }
812             },
813             //method of event handler
814             handler = {
815                 onSwitchNode: function (event, node) {
816                     var setting = data.getSetting(event.data.treeId);
817                     if (node.open) {
818                         if (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false) return true;
819                         data.getRoot(setting).expandTriggerFlag = true;
820                         view.switchNode(setting, node);
821                     } else {
822                         if (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false) return true;
823                         data.getRoot(setting).expandTriggerFlag = true;
824                         view.switchNode(setting, node);
825                     }
826                     return true;
827                 },
828                 onClickNode: function (event, node) {
829                     var setting = data.getSetting(event.data.treeId),
830                         clickFlag = ((setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey)) && data.isSelectedNode(setting, node)) ? 0 : (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey) && setting.view.selectedMulti) ? 2 : 1;
831                     if (tools.apply(setting.callback.beforeClick, [setting.treeId, node, clickFlag], true) == false) return true;
832                     if (clickFlag === 0) {
833                         view.cancelPreSelectedNode(setting, node);
834                     } else {
835                         view.selectNode(setting, node, clickFlag === 2);
836                     }
837                     setting.treeObj.trigger(consts.event.CLICK, [event, setting.treeId, node, clickFlag]);
838                     return true;
839                 },
840                 onZTreeMousedown: function (event, node) {
841                     var setting = data.getSetting(event.data.treeId);
842                     if (tools.apply(setting.callback.beforeMouseDown, [setting.treeId, node], true)) {
843                         tools.apply(setting.callback.onMouseDown, [event, setting.treeId, node]);
844                     }
845                     return true;
846                 },
847                 onZTreeMouseup: function (event, node) {
848                     var setting = data.getSetting(event.data.treeId);
849                     if (tools.apply(setting.callback.beforeMouseUp, [setting.treeId, node], true)) {
850                         tools.apply(setting.callback.onMouseUp, [event, setting.treeId, node]);
851                     }
852                     return true;
853                 },
854                 onZTreeDblclick: function (event, node) {
855                     var setting = data.getSetting(event.data.treeId);
856                     if (tools.apply(setting.callback.beforeDblClick, [setting.treeId, node], true)) {
857                         tools.apply(setting.callback.onDblClick, [event, setting.treeId, node]);
858                     }
859                     return true;
860                 },
861                 onZTreeContextmenu: function (event, node) {
862                     var setting = data.getSetting(event.data.treeId);
863                     if (tools.apply(setting.callback.beforeRightClick, [setting.treeId, node], true)) {
864                         tools.apply(setting.callback.onRightClick, [event, setting.treeId, node]);
865                     }
866                     return (typeof setting.callback.onRightClick) != "function";
867                 },
868                 onSelectStart: function (e) {
869                     var n = e.originalEvent.srcElement.nodeName.toLowerCase();
870                     return (n === "input" || n === "textarea");
871                 }
872             },
873             //method of tools for zTree
874             tools = {
875                 apply: function (fun, param, defaultValue) {
876                     if ((typeof fun) == "function") {
877                         return fun.apply(zt, param ? param : []);
878                     }
879                     return defaultValue;
880                 },
881                 canAsync: function (setting, node) {
882                     var children = data.nodeChildren(setting, node);
883                     var isParent = data.nodeIsParent(setting, node);
884                     return (setting.async.enable && node && isParent && !(node.zAsync || (children && children.length > 0)));
885                 },
886                 clone: function (obj) {
887                     if (obj === null) return null;
888                     var o = tools.isArray(obj) ? [] : {};
889                     for (var i in obj) {
890                         o[i] = (obj[i] instanceof Date) ? new Date(obj[i].getTime()) : (typeof obj[i] === "object" ? tools.clone(obj[i]) : obj[i]);
891                     }
892                     return o;
893                 },
894                 eqs: function (str1, str2) {
895                     return str1.toLowerCase() === str2.toLowerCase();
896                 },
897                 isArray: function (arr) {
898                     return Object.prototype.toString.apply(arr) === "[object Array]";
899                 },
900                 isElement: function (o) {
901                     return (
902                         typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
903                             o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"
904                     );
905                 },
906                 $: function (node, exp, setting) {
907                     if (!!exp && typeof exp != "string") {
908                         setting = exp;
909                         exp = "";
910                     }
911                     if (typeof node == "string") {
912                         return $(node, setting ? setting.treeObj.get(0).ownerDocument : null);
913                     } else {
914                         return $("#" + node.tId + exp, setting ? setting.treeObj : null);
915                     }
916                 },
917                 getMDom: function (setting, curDom, targetExpr) {
918                     if (!curDom) return null;
919                     while (curDom && curDom.id !== setting.treeId) {
920                         for (var i = 0, l = targetExpr.length; curDom.tagName && i < l; i++) {
921                             if (tools.eqs(curDom.tagName, targetExpr[i].tagName) && curDom.getAttribute(targetExpr[i].attrName) !== null) {
922                                 return curDom;
923                             }
924                         }
925                         curDom = curDom.parentNode;
926                     }
927                     return null;
928                 },
929                 getNodeMainDom: function (target) {
930                     return ($(target).parent("li").get(0) || $(target).parentsUntil("li").parent().get(0));
931                 },
932                 isChildOrSelf: function (dom, parentId) {
933                     return ($(dom).closest("#" + parentId).length > 0);
934                 },
935                 uCanDo: function (setting, e) {
936                     return true;
937                 }
938             },
939             //method of operate ztree dom
940             view = {
941                 addNodes: function (setting, parentNode, index, newNodes, isSilent) {
942                     var isParent = data.nodeIsParent(setting, parentNode);
943                     if (setting.data.keep.leaf && parentNode && !isParent) {
944                         return;
945                     }
946                     if (!tools.isArray(newNodes)) {
947                         newNodes = [newNodes];
948                     }
949                     if (setting.data.simpleData.enable) {
950                         newNodes = data.transformTozTreeFormat(setting, newNodes);
951                     }
952                     if (parentNode) {
953                         var target_switchObj = $$(parentNode, consts.id.SWITCH, setting),
954                             target_icoObj = $$(parentNode, consts.id.ICON, setting),
955                             target_ulObj = $$(parentNode, consts.id.UL, setting);
956
957                         if (!parentNode.open) {
958                             view.replaceSwitchClass(parentNode, target_switchObj, consts.folder.CLOSE);
959                             view.replaceIcoClass(parentNode, target_icoObj, consts.folder.CLOSE);
960                             parentNode.open = false;
961                             target_ulObj.css({
962                                 "display": "none"
963                             });
964                         }
965
966                         data.addNodesData(setting, parentNode, index, newNodes);
967                         view.createNodes(setting, parentNode.level + 1, newNodes, parentNode, index);
968                         if (!isSilent) {
969                             view.expandCollapseParentNode(setting, parentNode, true);
970                         }
971                     } else {
972                         data.addNodesData(setting, data.getRoot(setting), index, newNodes);
973                         view.createNodes(setting, 0, newNodes, null, index);
974                     }
975                 },
976                 appendNodes: function (setting, level, nodes, parentNode, index, initFlag, openFlag) {
977                     if (!nodes) return [];
978                     var html = [];
979
980                     var tmpPNode = (parentNode) ? parentNode : data.getRoot(setting),
981                         tmpPChild = data.nodeChildren(setting, tmpPNode),
982                         isFirstNode, isLastNode;
983
984                     if (!tmpPChild || index >= tmpPChild.length - nodes.length) {
985                         index = -1;
986                     }
987
988                     for (var i = 0, l = nodes.length; i < l; i++) {
989                         var node = nodes[i];
990                         if (initFlag) {
991                             isFirstNode = ((index === 0 || tmpPChild.length == nodes.length) && (i == 0));
992                             isLastNode = (index < 0 && i == (nodes.length - 1));
993                             data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag);
994                             data.addNodeCache(setting, node);
995                         }
996                         var isParent = data.nodeIsParent(setting, node);
997
998                         var childHtml = [];
999                         var children = data.nodeChildren(setting, node);
1000                         if (children && children.length > 0) {
1001                             //make child html first, because checkType
1002                             childHtml = view.appendNodes(setting, level + 1, children, node, -1, initFlag, openFlag && node.open);
1003                         }
1004                         if (openFlag) {
1005                             view.makeDOMNodeMainBefore(html, setting, node);
1006                             view.makeDOMNodeLine(html, setting, node);
1007                             data.getBeforeA(setting, node, html);
1008                             view.makeDOMNodeNameBefore(html, setting, node);
1009                             data.getInnerBeforeA(setting, node, html);
1010                             view.makeDOMNodeIcon(html, setting, node);
1011                             data.getInnerAfterA(setting, node, html);
1012                             view.makeDOMNodeNameAfter(html, setting, node);
1013                             data.getAfterA(setting, node, html);
1014                             if (isParent && node.open) {
1015                                 view.makeUlHtml(setting, node, html, childHtml.join(''));
1016                             }
1017                             view.makeDOMNodeMainAfter(html, setting, node);
1018                             data.addCreatedNode(setting, node);
1019                         }
1020                     }
1021                     return html;
1022                 },
1023                 appendParentULDom: function (setting, node) {
1024                     var html = [],
1025                         nObj = $$(node, setting);
1026                     if (!nObj.get(0) && !!node.parentTId) {
1027                         view.appendParentULDom(setting, node.getParentNode());
1028                         nObj = $$(node, setting);
1029                     }
1030                     var ulObj = $$(node, consts.id.UL, setting);
1031                     if (ulObj.get(0)) {
1032                         ulObj.remove();
1033                     }
1034                     var children = data.nodeChildren(setting, node),
1035                         childHtml = view.appendNodes(setting, node.level + 1, children, node, -1, false, true);
1036                     view.makeUlHtml(setting, node, html, childHtml.join(''));
1037                     nObj.append(html.join(''));
1038                 },
1039                 asyncNode: function (setting, node, isSilent, callback) {
1040                     var i, l;
1041                     var isParent = data.nodeIsParent(setting, node);
1042                     if (node && !isParent) {
1043                         tools.apply(callback);
1044                         return false;
1045                     } else if (node && node.isAjaxing) {
1046                         return false;
1047                     } else if (tools.apply(setting.callback.beforeAsync, [setting.treeId, node], true) == false) {
1048                         tools.apply(callback);
1049                         return false;
1050                     }
1051                     if (node) {
1052                         node.isAjaxing = true;
1053                         var icoObj = $$(node, consts.id.ICON, setting);
1054                         icoObj.attr({
1055                             "style": "",
1056                             "class": consts.className.BUTTON + " " + consts.className.ICO_LOADING
1057                         });
1058                     }
1059
1060                     var tmpParam = {};
1061                     var autoParam = tools.apply(setting.async.autoParam, [setting.treeId, node], setting.async.autoParam);
1062                     for (i = 0, l = autoParam.length; node && i < l; i++) {
1063                         var pKey = autoParam[i].split("="), spKey = pKey;
1064                         if (pKey.length > 1) {
1065                             spKey = pKey[1];
1066                             pKey = pKey[0];
1067                         }
1068                         tmpParam[spKey] = node[pKey];
1069                     }
1070                     var otherParam = tools.apply(setting.async.otherParam, [setting.treeId, node], setting.async.otherParam);
1071                     if (tools.isArray(otherParam)) {
1072                         for (i = 0, l = otherParam.length; i < l; i += 2) {
1073                             tmpParam[otherParam[i]] = otherParam[i + 1];
1074                         }
1075                     } else {
1076                         for (var p in otherParam) {
1077                             tmpParam[p] = otherParam[p];
1078                         }
1079                     }
1080
1081                     var _tmpV = data.getRoot(setting)._ver;
1082                     $.ajax({
1083                         contentType: setting.async.contentType,
1084                         cache: false,
1085                         type: setting.async.type,
1086                         url: tools.apply(setting.async.url, [setting.treeId, node], setting.async.url),
1087                         data: setting.async.contentType.indexOf('application/json') > -1 ? JSON.stringify(tmpParam) : tmpParam,
1088                         dataType: setting.async.dataType,
1089                         headers: setting.async.headers,
1090                         xhrFields: setting.async.xhrFields,
1091                         success: function (msg) {
1092                             if (_tmpV != data.getRoot(setting)._ver) {
1093                                 return;
1094                             }
1095                             var newNodes = [];
1096                             try {
1097                                 if (!msg || msg.length == 0) {
1098                                     newNodes = [];
1099                                 } else if (typeof msg == "string") {
1100                                     newNodes = eval("(" + msg + ")");
1101                                 } else {
1102                                     newNodes = msg;
1103                                 }
1104                             } catch (err) {
1105                                 newNodes = msg;
1106                             }
1107
1108                             if (node) {
1109                                 node.isAjaxing = null;
1110                                 node.zAsync = true;
1111                             }
1112                             view.setNodeLineIcos(setting, node);
1113                             if (newNodes && newNodes !== "") {
1114                                 newNodes = tools.apply(setting.async.dataFilter, [setting.treeId, node, newNodes], newNodes);
1115                                 view.addNodes(setting, node, -1, !!newNodes ? tools.clone(newNodes) : [], !!isSilent);
1116                             } else {
1117                                 view.addNodes(setting, node, -1, [], !!isSilent);
1118                             }
1119                             setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]);
1120                             tools.apply(callback);
1121                         },
1122                         error: function (XMLHttpRequest, textStatus, errorThrown) {
1123                             if (_tmpV != data.getRoot(setting)._ver) {
1124                                 return;
1125                             }
1126                             if (node) node.isAjaxing = null;
1127                             view.setNodeLineIcos(setting, node);
1128                             setting.treeObj.trigger(consts.event.ASYNC_ERROR, [setting.treeId, node, XMLHttpRequest, textStatus, errorThrown]);
1129                         }
1130                     });
1131                     return true;
1132                 },
1133                 cancelPreSelectedNode: function (setting, node, excludeNode) {
1134                     var list = data.getRoot(setting).curSelectedList,
1135                         i, n;
1136                     for (i = list.length - 1; i >= 0; i--) {
1137                         n = list[i];
1138                         if (node === n || (!node && (!excludeNode || excludeNode !== n))) {
1139                             $$(n, consts.id.A, setting).removeClass(consts.node.CURSELECTED);
1140                             if (node) {
1141                                 data.removeSelectedNode(setting, node);
1142                                 break;
1143                             } else {
1144                                 list.splice(i, 1);
1145                                 setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, n]);
1146                             }
1147                         }
1148                     }
1149                 },
1150                 createNodeCallback: function (setting) {
1151                     if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) {
1152                         var root = data.getRoot(setting);
1153                         while (root.createdNodes.length > 0) {
1154                             var node = root.createdNodes.shift();
1155                             tools.apply(setting.view.addDiyDom, [setting.treeId, node]);
1156                             if (!!setting.callback.onNodeCreated) {
1157                                 setting.treeObj.trigger(consts.event.NODECREATED, [setting.treeId, node]);
1158                             }
1159                         }
1160                     }
1161                 },
1162                 createNodes: function (setting, level, nodes, parentNode, index) {
1163                     if (!nodes || nodes.length == 0) return;
1164                     var root = data.getRoot(setting),
1165                         openFlag = !parentNode || parentNode.open || !!$$(data.nodeChildren(setting, parentNode)[0], setting).get(0);
1166                     root.createdNodes = [];
1167                     var zTreeHtml = view.appendNodes(setting, level, nodes, parentNode, index, true, openFlag),
1168                         parentObj, nextObj;
1169
1170                     if (!parentNode) {
1171                         parentObj = setting.treeObj;
1172                         //setting.treeObj.append(zTreeHtml.join(''));
1173                     } else {
1174                         var ulObj = $$(parentNode, consts.id.UL, setting);
1175                         if (ulObj.get(0)) {
1176                             parentObj = ulObj;
1177                             //ulObj.append(zTreeHtml.join(''));
1178                         }
1179                     }
1180                     if (parentObj) {
1181                         if (index >= 0) {
1182                             nextObj = parentObj.children()[index];
1183                         }
1184                         if (index >= 0 && nextObj) {
1185                             $(nextObj).before(zTreeHtml.join(''));
1186                         } else {
1187                             parentObj.append(zTreeHtml.join(''));
1188                         }
1189                     }
1190
1191                     view.createNodeCallback(setting);
1192                 },
1193                 destroy: function (setting) {
1194                     if (!setting) return;
1195                     data.initCache(setting);
1196                     data.initRoot(setting);
1197                     event.unbindTree(setting);
1198                     event.unbindEvent(setting);
1199                     setting.treeObj.empty();
1200                     delete settings[setting.treeId];
1201                 },
1202                 expandCollapseNode: function (setting, node, expandFlag, animateFlag, callback) {
1203                     var root = data.getRoot(setting);
1204                     var tmpCb, _callback;
1205                     if (!node) {
1206                         tools.apply(callback, []);
1207                         return;
1208                     }
1209                     var children = data.nodeChildren(setting, node);
1210                     var isParent = data.nodeIsParent(setting, node);
1211                     if (root.expandTriggerFlag) {
1212                         _callback = callback;
1213                         tmpCb = function () {
1214                             if (_callback) _callback();
1215                             if (node.open) {
1216                                 setting.treeObj.trigger(consts.event.EXPAND, [setting.treeId, node]);
1217                             } else {
1218                                 setting.treeObj.trigger(consts.event.COLLAPSE, [setting.treeId, node]);
1219                             }
1220                         };
1221                         callback = tmpCb;
1222                         root.expandTriggerFlag = false;
1223                     }
1224                     if (!node.open && isParent && ((!$$(node, consts.id.UL, setting).get(0)) || (children && children.length > 0 && !$$(children[0], setting).get(0)))) {
1225                         view.appendParentULDom(setting, node);
1226                         view.createNodeCallback(setting);
1227                     }
1228                     if (node.open == expandFlag) {
1229                         tools.apply(callback, []);
1230                         return;
1231                     }
1232                     var ulObj = $$(node, consts.id.UL, setting),
1233                         switchObj = $$(node, consts.id.SWITCH, setting),
1234                         icoObj = $$(node, consts.id.ICON, setting);
1235
1236                     if (isParent) {
1237                         node.open = !node.open;
1238                         if (node.iconOpen && node.iconClose) {
1239                             icoObj.attr("style", view.makeNodeIcoStyle(setting, node));
1240                         }
1241
1242                         if (node.open) {
1243                             view.replaceSwitchClass(node, switchObj, consts.folder.OPEN);
1244                             view.replaceIcoClass(node, icoObj, consts.folder.OPEN);
1245                             if (animateFlag == false || setting.view.expandSpeed == "") {
1246                                 ulObj.show();
1247                                 tools.apply(callback, []);
1248                             } else {
1249                                 if (children && children.length > 0) {
1250                                     ulObj.slideDown(setting.view.expandSpeed, callback);
1251                                 } else {
1252                                     ulObj.show();
1253                                     tools.apply(callback, []);
1254                                 }
1255                             }
1256                         } else {
1257                             view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE);
1258                             view.replaceIcoClass(node, icoObj, consts.folder.CLOSE);
1259                             if (animateFlag == false || setting.view.expandSpeed == "" || !(children && children.length > 0)) {
1260                                 ulObj.hide();
1261                                 tools.apply(callback, []);
1262                             } else {
1263                                 ulObj.slideUp(setting.view.expandSpeed, callback);
1264                             }
1265                         }
1266                     } else {
1267                         tools.apply(callback, []);
1268                     }
1269                 },
1270                 expandCollapseParentNode: function (setting, node, expandFlag, animateFlag, callback) {
1271                     if (!node) return;
1272                     if (!node.parentTId) {
1273                         view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback);
1274                         return;
1275                     } else {
1276                         view.expandCollapseNode(setting, node, expandFlag, animateFlag);
1277                     }
1278                     if (node.parentTId) {
1279                         view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, animateFlag, callback);
1280                     }
1281                 },
1282                 expandCollapseSonNode: function (setting, node, expandFlag, animateFlag, callback) {
1283                     var root = data.getRoot(setting),
1284                         treeNodes = (node) ? data.nodeChildren(setting, node) : data.nodeChildren(setting, root),
1285                         selfAnimateSign = (node) ? false : animateFlag,
1286                         expandTriggerFlag = data.getRoot(setting).expandTriggerFlag;
1287                     data.getRoot(setting).expandTriggerFlag = false;
1288                     if (treeNodes) {
1289                         for (var i = 0, l = treeNodes.length; i < l; i++) {
1290                             if (treeNodes[i]) view.expandCollapseSonNode(setting, treeNodes[i], expandFlag, selfAnimateSign);
1291                         }
1292                     }
1293                     data.getRoot(setting).expandTriggerFlag = expandTriggerFlag;
1294                     view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback);
1295                 },
1296                 isSelectedNode: function (setting, node) {
1297                     if (!node) {
1298                         return false;
1299                     }
1300                     var list = data.getRoot(setting).curSelectedList,
1301                         i;
1302                     for (i = list.length - 1; i >= 0; i--) {
1303                         if (node === list[i]) {
1304                             return true;
1305                         }
1306                     }
1307                     return false;
1308                 },
1309                 makeDOMNodeIcon: function (html, setting, node) {
1310                     var nameStr = data.nodeName(setting, node),
1311                         name = setting.view.nameIsHTML ? nameStr : nameStr.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1312                     html.push("<span id='", node.tId, consts.id.ICON,
1313                         "' title='' treeNode", consts.id.ICON, " class='", view.makeNodeIcoClass(setting, node),
1314                         "' style='", view.makeNodeIcoStyle(setting, node), "'></span><span id='", node.tId, consts.id.SPAN,
1315                         "' class='", consts.className.NAME,
1316                         "'>", name, "</span>");
1317                 },
1318                 makeDOMNodeLine: function (html, setting, node) {
1319                     html.push("<span id='", node.tId, consts.id.SWITCH, "' title='' class='", view.makeNodeLineClass(setting, node), "' treeNode", consts.id.SWITCH, "></span>");
1320                 },
1321                 makeDOMNodeMainAfter: function (html, setting, node) {
1322                     html.push("</li>");
1323                 },
1324                 makeDOMNodeMainBefore: function (html, setting, node) {
1325                     html.push("<li id='", node.tId, "' class='", consts.className.LEVEL, node.level, "' tabindex='0' hidefocus='true' treenode>");
1326                 },
1327                 makeDOMNodeNameAfter: function (html, setting, node) {
1328                     html.push("</a>");
1329                 },
1330                 makeDOMNodeNameBefore: function (html, setting, node) {
1331                     var title = data.nodeTitle(setting, node),
1332                         url = view.makeNodeUrl(setting, node),
1333                         fontcss = view.makeNodeFontCss(setting, node),
1334                         fontStyle = [];
1335                     for (var f in fontcss) {
1336                         fontStyle.push(f, ":", fontcss[f], ";");
1337                     }
1338                     html.push("<a id='", node.tId, consts.id.A, "' class='", consts.className.LEVEL, node.level, "' treeNode", consts.id.A, " onclick=\"", (node.click || ''),
1339                         "\" ", ((url != null && url.length > 0) ? "href='" + url + "'" : ""), " target='", view.makeNodeTarget(node), "' style='", fontStyle.join(''),
1340                         "'");
1341                     if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle) && title) {
1342                         html.push("title='", title.replace(/'/g, "&#39;").replace(/</g, '&lt;').replace(/>/g, '&gt;'), "'");
1343                     }
1344                     html.push(">");
1345                 },
1346                 makeNodeFontCss: function (setting, node) {
1347                     var fontCss = tools.apply(setting.view.fontCss, [setting.treeId, node], setting.view.fontCss);
1348                     return (fontCss && ((typeof fontCss) != "function")) ? fontCss : {};
1349                 },
1350                 makeNodeIcoClass: function (setting, node) {
1351                     var icoCss = ["ico"];
1352                     if (!node.isAjaxing) {
1353                         var isParent = data.nodeIsParent(setting, node);
1354                         icoCss[0] = (node.iconSkin ? node.iconSkin + "_" : "") + icoCss[0];
1355                         if (isParent) {
1356                             icoCss.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE);
1357                         } else {
1358                             icoCss.push(consts.folder.DOCU);
1359                         }
1360                     }
1361                     return consts.className.BUTTON + " " + icoCss.join('_');
1362                 },
1363                 makeNodeIcoStyle: function (setting, node) {
1364                     var icoStyle = [];
1365                     if (!node.isAjaxing) {
1366                         var isParent = data.nodeIsParent(setting, node);
1367                         var icon = (isParent && node.iconOpen && node.iconClose) ? (node.open ? node.iconOpen : node.iconClose) : node[setting.data.key.icon];
1368                         if (icon) icoStyle.push("background:url(", icon, ") 0 0 no-repeat;");
1369                         if (setting.view.showIcon == false || !tools.apply(setting.view.showIcon, [setting.treeId, node], true)) {
1370                             icoStyle.push("width:0px;height:0px;");
1371                         }
1372                     }
1373                     return icoStyle.join('');
1374                 },
1375                 makeNodeLineClass: function (setting, node) {
1376                     var lineClass = [];
1377                     if (setting.view.showLine) {
1378                         if (node.level == 0 && node.isFirstNode && node.isLastNode) {
1379                             lineClass.push(consts.line.ROOT);
1380                         } else if (node.level == 0 && node.isFirstNode) {
1381                             lineClass.push(consts.line.ROOTS);
1382                         } else if (node.isLastNode) {
1383                             lineClass.push(consts.line.BOTTOM);
1384                         } else {
1385                             lineClass.push(consts.line.CENTER);
1386                         }
1387                     } else {
1388                         lineClass.push(consts.line.NOLINE);
1389                     }
1390                     if (data.nodeIsParent(setting, node)) {
1391                         lineClass.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE);
1392                     } else {
1393                         lineClass.push(consts.folder.DOCU);
1394                     }
1395                     return view.makeNodeLineClassEx(node) + lineClass.join('_');
1396                 },
1397                 makeNodeLineClassEx: function (node) {
1398                     return consts.className.BUTTON + " " + consts.className.LEVEL + node.level + " " + consts.className.SWITCH + " ";
1399                 },
1400                 makeNodeTarget: function (node) {
1401                     return (node.target || "_blank");
1402                 },
1403                 makeNodeUrl: function (setting, node) {
1404                     var urlKey = setting.data.key.url;
1405                     return node[urlKey] ? node[urlKey] : null;
1406                 },
1407                 makeUlHtml: function (setting, node, html, content) {
1408                     html.push("<ul id='", node.tId, consts.id.UL, "' class='", consts.className.LEVEL, node.level, " ", view.makeUlLineClass(setting, node), "' style='display:", (node.open ? "block" : "none"), "'>");
1409                     html.push(content);
1410                     html.push("</ul>");
1411                 },
1412                 makeUlLineClass: function (setting, node) {
1413                     return ((setting.view.showLine && !node.isLastNode) ? consts.line.LINE : "");
1414                 },
1415                 removeChildNodes: function (setting, node) {
1416                     if (!node) return;
1417                     var nodes = data.nodeChildren(setting, node);
1418                     if (!nodes) return;
1419
1420                     for (var i = 0, l = nodes.length; i < l; i++) {
1421                         data.removeNodeCache(setting, nodes[i]);
1422                     }
1423                     data.removeSelectedNode(setting);
1424                     delete node[setting.data.key.children];
1425
1426                     if (!setting.data.keep.parent) {
1427                         data.nodeIsParent(setting, node, false);
1428                         node.open = false;
1429                         var tmp_switchObj = $$(node, consts.id.SWITCH, setting),
1430                             tmp_icoObj = $$(node, consts.id.ICON, setting);
1431                         view.replaceSwitchClass(node, tmp_switchObj, consts.folder.DOCU);
1432                         view.replaceIcoClass(node, tmp_icoObj, consts.folder.DOCU);
1433                         $$(node, consts.id.UL, setting).remove();
1434                     } else {
1435                         $$(node, consts.id.UL, setting).empty();
1436                     }
1437                 },
1438                 scrollIntoView: function (setting, dom) {
1439                     if (!dom) {
1440                         return;
1441                     }
1442                     // support IE 7
1443                     if (typeof Element === 'undefined') {
1444                         var contRect = setting.treeObj.get(0).getBoundingClientRect(),
1445                             findMeRect = dom.getBoundingClientRect();
1446                         if (findMeRect.top < contRect.top || findMeRect.bottom > contRect.bottom
1447                             || findMeRect.right > contRect.right || findMeRect.left < contRect.left) {
1448                             dom.scrollIntoView();
1449                         }
1450                         return;
1451                     }
1452                     // CC-BY jocki84@googlemail.com, https://gist.github.com/jocki84/6ffafd003387179a988e
1453                     if (!Element.prototype.scrollIntoViewIfNeeded) {
1454                         Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
1455                             "use strict";
1456
1457                             function makeRange(start, length) {
1458                                 return {"start": start, "length": length, "end": start + length};
1459                             }
1460
1461                             function coverRange(inner, outer) {
1462                                 if (
1463                                     false === centerIfNeeded ||
1464                                     (outer.start < inner.end && inner.start < outer.end)
1465                                 ) {
1466                                     return Math.max(
1467                                         inner.end - outer.length,
1468                                         Math.min(outer.start, inner.start)
1469                                     );
1470                                 }
1471                                 return (inner.start + inner.end - outer.length) / 2;
1472                             }
1473
1474                             function makePoint(x, y) {
1475                                 return {
1476                                     "x": x,
1477                                     "y": y,
1478                                     "translate": function translate(dX, dY) {
1479                                         return makePoint(x + dX, y + dY);
1480                                     }
1481                                 };
1482                             }
1483
1484                             function absolute(elem, pt) {
1485                                 while (elem) {
1486                                     pt = pt.translate(elem.offsetLeft, elem.offsetTop);
1487                                     elem = elem.offsetParent;
1488                                 }
1489                                 return pt;
1490                             }
1491
1492                             var target = absolute(this, makePoint(0, 0)),
1493                                 extent = makePoint(this.offsetWidth, this.offsetHeight),
1494                                 elem = this.parentNode,
1495                                 origin;
1496
1497                             while (elem instanceof HTMLElement) {
1498                                 // Apply desired scroll amount.
1499                                 origin = absolute(elem, makePoint(elem.clientLeft, elem.clientTop));
1500                                 elem.scrollLeft = coverRange(
1501                                     makeRange(target.x - origin.x, extent.x),
1502                                     makeRange(elem.scrollLeft, elem.clientWidth)
1503                                 );
1504                                 elem.scrollTop = coverRange(
1505                                     makeRange(target.y - origin.y, extent.y),
1506                                     makeRange(elem.scrollTop, elem.clientHeight)
1507                                 );
1508
1509                                 // Determine actual scroll amount by reading back scroll properties.
1510                                 target = target.translate(-elem.scrollLeft, -elem.scrollTop);
1511                                 elem = elem.parentNode;
1512                             }
1513                         };
1514                     }
1515                     dom.scrollIntoViewIfNeeded();
1516                 },
1517                 setFirstNode: function (setting, parentNode) {
1518                     var children = data.nodeChildren(setting, parentNode);
1519                     if (children.length > 0) {
1520                         children[0].isFirstNode = true;
1521                     }
1522                 },
1523                 setLastNode: function (setting, parentNode) {
1524                     var children = data.nodeChildren(setting, parentNode);
1525                     if (children.length > 0) {
1526                         children[children.length - 1].isLastNode = true;
1527                     }
1528                 },
1529                 removeNode: function (setting, node) {
1530                     var root = data.getRoot(setting),
1531                         parentNode = (node.parentTId) ? node.getParentNode() : root;
1532
1533                     node.isFirstNode = false;
1534                     node.isLastNode = false;
1535                     node.getPreNode = function () {
1536                         return null;
1537                     };
1538                     node.getNextNode = function () {
1539                         return null;
1540                     };
1541
1542                     if (!data.getNodeCache(setting, node.tId)) {
1543                         return;
1544                     }
1545
1546                     $$(node, setting).remove();
1547                     data.removeNodeCache(setting, node);
1548                     data.removeSelectedNode(setting, node);
1549
1550                     var children = data.nodeChildren(setting, parentNode);
1551                     for (var i = 0, l = children.length; i < l; i++) {
1552                         if (children[i].tId == node.tId) {
1553                             children.splice(i, 1);
1554                             break;
1555                         }
1556                     }
1557                     view.setFirstNode(setting, parentNode);
1558                     view.setLastNode(setting, parentNode);
1559
1560                     var tmp_ulObj, tmp_switchObj, tmp_icoObj,
1561                         childLength = children.length;
1562
1563                     //repair nodes old parent
1564                     if (!setting.data.keep.parent && childLength == 0) {
1565                         //old parentNode has no child nodes
1566                         data.nodeIsParent(setting, parentNode, false);
1567                         parentNode.open = false;
1568                         delete parentNode[setting.data.key.children];
1569                         tmp_ulObj = $$(parentNode, consts.id.UL, setting);
1570                         tmp_switchObj = $$(parentNode, consts.id.SWITCH, setting);
1571                         tmp_icoObj = $$(parentNode, consts.id.ICON, setting);
1572                         view.replaceSwitchClass(parentNode, tmp_switchObj, consts.folder.DOCU);
1573                         view.replaceIcoClass(parentNode, tmp_icoObj, consts.folder.DOCU);
1574                         tmp_ulObj.css("display", "none");
1575
1576                     } else if (setting.view.showLine && childLength > 0) {
1577                         //old parentNode has child nodes
1578                         var newLast = children[childLength - 1];
1579                         tmp_ulObj = $$(newLast, consts.id.UL, setting);
1580                         tmp_switchObj = $$(newLast, consts.id.SWITCH, setting);
1581                         tmp_icoObj = $$(newLast, consts.id.ICON, setting);
1582                         if (parentNode == root) {
1583                             if (children.length == 1) {
1584                                 //node was root, and ztree has only one root after move node
1585                                 view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.ROOT);
1586                             } else {
1587                                 var tmp_first_switchObj = $$(children[0], consts.id.SWITCH, setting);
1588                                 view.replaceSwitchClass(children[0], tmp_first_switchObj, consts.line.ROOTS);
1589                                 view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM);
1590                             }
1591                         } else {
1592                             view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM);
1593                         }
1594                         tmp_ulObj.removeClass(consts.line.LINE);
1595                     }
1596                 },
1597                 replaceIcoClass: function (node, obj, newName) {
1598                     if (!obj || node.isAjaxing) return;
1599                     var tmpName = obj.attr("class");
1600                     if (tmpName == undefined) return;
1601                     var tmpList = tmpName.split("_");
1602                     switch (newName) {
1603                         case consts.folder.OPEN:
1604                         case consts.folder.CLOSE:
1605                         case consts.folder.DOCU:
1606                             tmpList[tmpList.length - 1] = newName;
1607                             break;
1608                     }
1609                     obj.attr("class", tmpList.join("_"));
1610                 },
1611                 replaceSwitchClass: function (node, obj, newName) {
1612                     if (!obj) return;
1613                     var tmpName = obj.attr("class");
1614                     if (tmpName == undefined) return;
1615                     var tmpList = tmpName.split("_");
1616                     switch (newName) {
1617                         case consts.line.ROOT:
1618                         case consts.line.ROOTS:
1619                         case consts.line.CENTER:
1620                         case consts.line.BOTTOM:
1621                         case consts.line.NOLINE:
1622                             tmpList[0] = view.makeNodeLineClassEx(node) + newName;
1623                             break;
1624                         case consts.folder.OPEN:
1625                         case consts.folder.CLOSE:
1626                         case consts.folder.DOCU:
1627                             tmpList[1] = newName;
1628                             break;
1629                     }
1630                     obj.attr("class", tmpList.join("_"));
1631                     if (newName !== consts.folder.DOCU) {
1632                         obj.removeAttr("disabled");
1633                     } else {
1634                         obj.attr("disabled", "disabled");
1635                     }
1636                 },
1637                 selectNode: function (setting, node, addFlag) {
1638                     if (!addFlag) {
1639                         view.cancelPreSelectedNode(setting, null, node);
1640                     }
1641                     $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED);
1642                     data.addSelectedNode(setting, node);
1643                     setting.treeObj.trigger(consts.event.SELECTED, [setting.treeId, node]);
1644                 },
1645                 setNodeFontCss: function (setting, treeNode) {
1646                     var aObj = $$(treeNode, consts.id.A, setting),
1647                         fontCss = view.makeNodeFontCss(setting, treeNode);
1648                     if (fontCss) {
1649                         aObj.css(fontCss);
1650                     }
1651                 },
1652                 setNodeLineIcos: function (setting, node) {
1653                     if (!node) return;
1654                     var switchObj = $$(node, consts.id.SWITCH, setting),
1655                         ulObj = $$(node, consts.id.UL, setting),
1656                         icoObj = $$(node, consts.id.ICON, setting),
1657                         ulLine = view.makeUlLineClass(setting, node);
1658                     if (ulLine.length == 0) {
1659                         ulObj.removeClass(consts.line.LINE);
1660                     } else {
1661                         ulObj.addClass(ulLine);
1662                     }
1663                     switchObj.attr("class", view.makeNodeLineClass(setting, node));
1664                     if (data.nodeIsParent(setting, node)) {
1665                         switchObj.removeAttr("disabled");
1666                     } else {
1667                         switchObj.attr("disabled", "disabled");
1668                     }
1669                     icoObj.removeAttr("style");
1670                     icoObj.attr("style", view.makeNodeIcoStyle(setting, node));
1671                     icoObj.attr("class", view.makeNodeIcoClass(setting, node));
1672                 },
1673                 setNodeName: function (setting, node) {
1674                     var title = data.nodeTitle(setting, node),
1675                         nObj = $$(node, consts.id.SPAN, setting);
1676                     nObj.empty();
1677                     if (setting.view.nameIsHTML) {
1678                         nObj.html(data.nodeName(setting, node));
1679                     } else {
1680                         nObj.text(data.nodeName(setting, node));
1681                     }
1682                     if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle)) {
1683                         var aObj = $$(node, consts.id.A, setting);
1684                         aObj.attr("title", !title ? "" : title);
1685                     }
1686                 },
1687                 setNodeTarget: function (setting, node) {
1688                     var aObj = $$(node, consts.id.A, setting);
1689                     aObj.attr("target", view.makeNodeTarget(node));
1690                 },
1691                 setNodeUrl: function (setting, node) {
1692                     var aObj = $$(node, consts.id.A, setting),
1693                         url = view.makeNodeUrl(setting, node);
1694                     if (url == null || url.length == 0) {
1695                         aObj.removeAttr("href");
1696                     } else {
1697                         aObj.attr("href", url);
1698                     }
1699                 },
1700                 switchNode: function (setting, node) {
1701                     if (node.open || !tools.canAsync(setting, node)) {
1702                         view.expandCollapseNode(setting, node, !node.open);
1703                     } else if (setting.async.enable) {
1704                         if (!view.asyncNode(setting, node)) {
1705                             view.expandCollapseNode(setting, node, !node.open);
1706                             return;
1707                         }
1708                     } else if (node) {
1709                         view.expandCollapseNode(setting, node, !node.open);
1710                     }
1711                 }
1712             };
1713         // zTree defind
1714         $.fn.zTree = {
1715             consts: _consts,
1716             _z: {
1717                 tools: tools,
1718                 view: view,
1719                 event: event,
1720                 data: data
1721             },
1722             getZTreeObj: function (treeId) {
1723                 var o = data.getZTreeTools(treeId);
1724                 return o ? o : null;
1725             },
1726             destroy: function (treeId) {
1727                 if (!!treeId && treeId.length > 0) {
1728                     view.destroy(data.getSetting(treeId));
1729                 } else {
1730                     for (var s in settings) {
1731                         view.destroy(settings[s]);
1732                     }
1733                 }
1734             },
1735             init: function (obj, zSetting, zNodes) {
1736                 var setting = tools.clone(_setting);
1737                 $.extend(true, setting, zSetting);
1738                 setting.treeId = obj.attr("id");
1739                 setting.treeObj = obj;
1740                 setting.treeObj.empty();
1741                 settings[setting.treeId] = setting;
1742                 //For some older browser,(e.g., ie6)
1743                 if (typeof document.body.style.maxHeight === "undefined") {
1744                     setting.view.expandSpeed = "";
1745                 }
1746                 data.initRoot(setting);
1747                 var root = data.getRoot(setting);
1748                 zNodes = zNodes ? tools.clone(tools.isArray(zNodes) ? zNodes : [zNodes]) : [];
1749                 if (setting.data.simpleData.enable) {
1750                     data.nodeChildren(setting, root, data.transformTozTreeFormat(setting, zNodes));
1751                 } else {
1752                     data.nodeChildren(setting, root, zNodes);
1753                 }
1754
1755                 data.initCache(setting);
1756                 event.unbindTree(setting);
1757                 event.bindTree(setting);
1758                 event.unbindEvent(setting);
1759                 event.bindEvent(setting);
1760
1761                 var zTreeTools = {
1762                     setting: setting,
1763                     addNodes: function (parentNode, index, newNodes, isSilent) {
1764                         if (!parentNode) parentNode = null;
1765                         var isParent = data.nodeIsParent(setting, parentNode);
1766                         if (parentNode && !isParent && setting.data.keep.leaf) return null;
1767
1768                         var i = parseInt(index, 10);
1769                         if (isNaN(i)) {
1770                             isSilent = !!newNodes;
1771                             newNodes = index;
1772                             index = -1;
1773                         } else {
1774                             index = i;
1775                         }
1776                         if (!newNodes) return null;
1777
1778
1779                         var xNewNodes = tools.clone(tools.isArray(newNodes) ? newNodes : [newNodes]);
1780
1781                         function addCallback() {
1782                             view.addNodes(setting, parentNode, index, xNewNodes, (isSilent == true));
1783                         }
1784
1785                         if (tools.canAsync(setting, parentNode)) {
1786                             view.asyncNode(setting, parentNode, isSilent, addCallback);
1787                         } else {
1788                             addCallback();
1789                         }
1790                         return xNewNodes;
1791                     },
1792                     cancelSelectedNode: function (node) {
1793                         view.cancelPreSelectedNode(setting, node);
1794                     },
1795                     destroy: function () {
1796                         view.destroy(setting);
1797                     },
1798                     expandAll: function (expandFlag) {
1799                         expandFlag = !!expandFlag;
1800                         view.expandCollapseSonNode(setting, null, expandFlag, true);
1801                         return expandFlag;
1802                     },
1803                     expandNode: function (node, expandFlag, sonSign, focus, callbackFlag) {
1804                         if (!node || !data.nodeIsParent(setting, node)) return null;
1805                         if (expandFlag !== true && expandFlag !== false) {
1806                             expandFlag = !node.open;
1807                         }
1808                         callbackFlag = !!callbackFlag;
1809
1810                         if (callbackFlag && expandFlag && (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false)) {
1811                             return null;
1812                         } else if (callbackFlag && !expandFlag && (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false)) {
1813                             return null;
1814                         }
1815                         if (expandFlag && node.parentTId) {
1816                             view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, false);
1817                         }
1818                         if (expandFlag === node.open && !sonSign) {
1819                             return null;
1820                         }
1821
1822                         data.getRoot(setting).expandTriggerFlag = callbackFlag;
1823                         if (!tools.canAsync(setting, node) && sonSign) {
1824                             view.expandCollapseSonNode(setting, node, expandFlag, true, showNodeFocus);
1825                         } else {
1826                             node.open = !expandFlag;
1827                             view.switchNode(this.setting, node);
1828                             showNodeFocus();
1829                         }
1830                         return expandFlag;
1831
1832                         function showNodeFocus() {
1833                             var a = $$(node, setting).get(0);
1834                             if (a && focus !== false) {
1835                                 view.scrollIntoView(setting, a);
1836                             }
1837                         }
1838                     },
1839                     getNodes: function () {
1840                         return data.getNodes(setting);
1841                     },
1842                     getNodeByParam: function (key, value, parentNode) {
1843                         if (!key) return null;
1844                         return data.getNodeByParam(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value);
1845                     },
1846                     getNodeByTId: function (tId) {
1847                         return data.getNodeCache(setting, tId);
1848                     },
1849                     getNodesByParam: function (key, value, parentNode) {
1850                         if (!key) return null;
1851                         return data.getNodesByParam(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value);
1852                     },
1853                     getNodesByParamFuzzy: function (key, value, parentNode) {
1854                         if (!key) return null;
1855                         return data.getNodesByParamFuzzy(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value);
1856                     },
1857                     getNodesByFilter: function (filter, isSingle, parentNode, invokeParam) {
1858                         isSingle = !!isSingle;
1859                         if (!filter || (typeof filter != "function")) return (isSingle ? null : []);
1860                         return data.getNodesByFilter(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), filter, isSingle, invokeParam);
1861                     },
1862                     getNodeIndex: function (node) {
1863                         if (!node) return null;
1864                         var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting);
1865                         var children = data.nodeChildren(setting, parentNode);
1866                         for (var i = 0, l = children.length; i < l; i++) {
1867                             if (children[i] == node) return i;
1868                         }
1869                         return -1;
1870                     },
1871                     getSelectedNodes: function () {
1872                         var r = [], list = data.getRoot(setting).curSelectedList;
1873                         for (var i = 0, l = list.length; i < l; i++) {
1874                             r.push(list[i]);
1875                         }
1876                         return r;
1877                     },
1878                     isSelectedNode: function (node) {
1879                         return data.isSelectedNode(setting, node);
1880                     },
1881                     reAsyncChildNodesPromise: function (parentNode, reloadType, isSilent) {
1882                         var promise = new Promise(function (resolve, reject) {
1883                             try {
1884                                 zTreeTools.reAsyncChildNodes(parentNode, reloadType, isSilent, function () {
1885                                     resolve(parentNode);
1886                                 });
1887                             } catch (e) {
1888                                 reject(e);
1889                             }
1890                         });
1891                         return promise;
1892                     },
1893                     reAsyncChildNodes: function (parentNode, reloadType, isSilent, callback) {
1894                         if (!this.setting.async.enable) return;
1895                         var isRoot = !parentNode;
1896                         if (isRoot) {
1897                             parentNode = data.getRoot(setting);
1898                         }
1899                         if (reloadType == "refresh") {
1900                             var children = data.nodeChildren(setting, parentNode);
1901                             for (var i = 0, l = children ? children.length : 0; i < l; i++) {
1902                                 data.removeNodeCache(setting, children[i]);
1903                             }
1904                             data.removeSelectedNode(setting);
1905                             data.nodeChildren(setting, parentNode, []);
1906                             if (isRoot) {
1907                                 this.setting.treeObj.empty();
1908                             } else {
1909                                 var ulObj = $$(parentNode, consts.id.UL, setting);
1910                                 ulObj.empty();
1911                             }
1912                         }
1913                         view.asyncNode(this.setting, isRoot ? null : parentNode, !!isSilent, callback);
1914                     },
1915                     refresh: function () {
1916                         this.setting.treeObj.empty();
1917                         var root = data.getRoot(setting),
1918                             nodes = data.nodeChildren(setting, root);
1919                         data.initRoot(setting);
1920                         data.nodeChildren(setting, root, nodes);
1921                         data.initCache(setting);
1922                         view.createNodes(setting, 0, data.nodeChildren(setting, root), null, -1);
1923                     },
1924                     removeChildNodes: function (node) {
1925                         if (!node) return null;
1926                         var nodes = data.nodeChildren(setting, node);
1927                         view.removeChildNodes(setting, node);
1928                         return nodes ? nodes : null;
1929                     },
1930                     removeNode: function (node, callbackFlag) {
1931                         if (!node) return;
1932                         callbackFlag = !!callbackFlag;
1933                         if (callbackFlag && tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return;
1934                         view.removeNode(setting, node);
1935                         if (callbackFlag) {
1936                             this.setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]);
1937                         }
1938                     },
1939                     selectNode: function (node, addFlag, isSilent) {
1940                         if (!node) return;
1941                         if (tools.uCanDo(setting)) {
1942                             addFlag = setting.view.selectedMulti && addFlag;
1943                             if (node.parentTId) {
1944                                 view.expandCollapseParentNode(setting, node.getParentNode(), true, false, showNodeFocus);
1945                             } else if (!isSilent) {
1946                                 try {
1947                                     $$(node, setting).focus().blur();
1948                                 } catch (e) {
1949                                 }
1950                             }
1951                             view.selectNode(setting, node, addFlag);
1952                         }
1953
1954                         function showNodeFocus() {
1955                             if (isSilent) {
1956                                 return;
1957                             }
1958                             var a = $$(node, setting).get(0);
1959                             view.scrollIntoView(setting, a);
1960                         }
1961                     },
1962                     transformTozTreeNodes: function (simpleNodes) {
1963                         return data.transformTozTreeFormat(setting, simpleNodes);
1964                     },
1965                     transformToArray: function (nodes) {
1966                         return data.transformToArrayFormat(setting, nodes);
1967                     },
1968                     updateNode: function (node, checkTypeFlag) {
1969                         if (!node) return;
1970                         var nObj = $$(node, setting);
1971                         if (nObj.get(0) && tools.uCanDo(setting)) {
1972                             view.setNodeName(setting, node);
1973                             view.setNodeTarget(setting, node);
1974                             view.setNodeUrl(setting, node);
1975                             view.setNodeLineIcos(setting, node);
1976                             view.setNodeFontCss(setting, node);
1977                         }
1978                     }
1979                 };
1980                 root.treeTools = zTreeTools;
1981                 data.setZTreeTools(setting, zTreeTools);
1982                 var children = data.nodeChildren(setting, root);
1983                 if (children && children.length > 0) {
1984                     view.createNodes(setting, 0, children, null, -1);
1985                 } else if (setting.async.enable && setting.async.url && setting.async.url !== '') {
1986                     view.asyncNode(setting);
1987                 }
1988                 return zTreeTools;
1989             }
1990         };
1991
1992         var zt = $.fn.zTree,
1993             $$ = tools.$,
1994             consts = zt.consts;
1995     })(jQuery);
1996     /*
1997  * JQuery zTree excheck v3.5.40
1998  * http://treejs.cn/
1999  *
2000  * Copyright (c) 2010 Hunter.z
2001  *
2002  * Licensed same as jquery - MIT License
2003  * http://www.opensource.org/licenses/mit-license.php
2004  *
2005  * email: hunter.z@263.net
2006  * Date: 2019-01-18
2007  */
2008     (function ($) {
2009         //default consts of excheck
2010         var _consts = {
2011                 event: {
2012                     CHECK: "ztree_check"
2013                 },
2014                 id: {
2015                     CHECK: "_check"
2016                 },
2017                 checkbox: {
2018                     STYLE: "checkbox",
2019                     DEFAULT: "chk",
2020                     DISABLED: "disable",
2021                     FALSE: "false",
2022                     TRUE: "true",
2023                     FULL: "full",
2024                     PART: "part",
2025                     FOCUS: "focus"
2026                 },
2027                 radio: {
2028                     STYLE: "radio",
2029                     TYPE_ALL: "all",
2030                     TYPE_LEVEL: "level"
2031                 }
2032             },
2033             //default setting of excheck
2034             _setting = {
2035                 check: {
2036                     enable: false,
2037                     autoCheckTrigger: false,
2038                     chkStyle: _consts.checkbox.STYLE,
2039                     nocheckInherit: false,
2040                     chkDisabledInherit: false,
2041                     radioType: _consts.radio.TYPE_LEVEL,
2042                     chkboxType: {
2043                         "Y": "ps",
2044                         "N": "ps"
2045                     }
2046                 },
2047                 data: {
2048                     key: {
2049                         checked: "checked"
2050                     }
2051                 },
2052                 callback: {
2053                     beforeCheck: null,
2054                     onCheck: null
2055                 }
2056             },
2057             //default root of excheck
2058             _initRoot = function (setting) {
2059                 var r = data.getRoot(setting);
2060                 r.radioCheckedList = [];
2061             },
2062             //default cache of excheck
2063             _initCache = function (treeId) {
2064             },
2065             //default bind event of excheck
2066             _bindEvent = function (setting) {
2067                 var o = setting.treeObj,
2068                     c = consts.event;
2069                 o.bind(c.CHECK, function (event, srcEvent, treeId, node) {
2070                     event.srcEvent = srcEvent;
2071                     tools.apply(setting.callback.onCheck, [event, treeId, node]);
2072                 });
2073             },
2074             _unbindEvent = function (setting) {
2075                 var o = setting.treeObj,
2076                     c = consts.event;
2077                 o.unbind(c.CHECK);
2078             },
2079             //default event proxy of excheck
2080             _eventProxy = function (e) {
2081                 var target = e.target,
2082                     setting = data.getSetting(e.data.treeId),
2083                     tId = "", node = null,
2084                     nodeEventType = "", treeEventType = "",
2085                     nodeEventCallback = null, treeEventCallback = null;
2086
2087                 if (tools.eqs(e.type, "mouseover")) {
2088                     if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) {
2089                         tId = tools.getNodeMainDom(target).id;
2090                         nodeEventType = "mouseoverCheck";
2091                     }
2092                 } else if (tools.eqs(e.type, "mouseout")) {
2093                     if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) {
2094                         tId = tools.getNodeMainDom(target).id;
2095                         nodeEventType = "mouseoutCheck";
2096                     }
2097                 } else if (tools.eqs(e.type, "click")) {
2098                     if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) {
2099                         tId = tools.getNodeMainDom(target).id;
2100                         nodeEventType = "checkNode";
2101                     }
2102                 }
2103                 if (tId.length > 0) {
2104                     node = data.getNodeCache(setting, tId);
2105                     switch (nodeEventType) {
2106                         case "checkNode" :
2107                             nodeEventCallback = _handler.onCheckNode;
2108                             break;
2109                         case "mouseoverCheck" :
2110                             nodeEventCallback = _handler.onMouseoverCheck;
2111                             break;
2112                         case "mouseoutCheck" :
2113                             nodeEventCallback = _handler.onMouseoutCheck;
2114                             break;
2115                     }
2116                 }
2117                 var proxyResult = {
2118                     stop: nodeEventType === "checkNode",
2119                     node: node,
2120                     nodeEventType: nodeEventType,
2121                     nodeEventCallback: nodeEventCallback,
2122                     treeEventType: treeEventType,
2123                     treeEventCallback: treeEventCallback
2124                 };
2125                 return proxyResult
2126             },
2127             //default init node of excheck
2128             _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) {
2129                 if (!n) return;
2130                 var checked = data.nodeChecked(setting, n);
2131                 n.checkedOld = checked;
2132                 if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true");
2133                 n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck);
2134                 if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true");
2135                 n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled);
2136                 if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true");
2137                 n.halfCheck = !!n.halfCheck;
2138                 n.check_Child_State = -1;
2139                 n.check_Focus = false;
2140                 n.getCheckStatus = function () {
2141                     return data.getCheckStatus(setting, n);
2142                 };
2143
2144                 if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && checked) {
2145                     var r = data.getRoot(setting);
2146                     r.radioCheckedList.push(n);
2147                 }
2148             },
2149             //add dom for check
2150             _beforeA = function (setting, node, html) {
2151                 if (setting.check.enable) {
2152                     data.makeChkFlag(setting, node);
2153                     html.push("<span ID='", node.tId, consts.id.CHECK, "' class='", view.makeChkClass(setting, node), "' treeNode", consts.id.CHECK, (node.nocheck === true ? " style='display:none;'" : ""), "></span>");
2154                 }
2155             },
2156             //update zTreeObj, add method of check
2157             _zTreeTools = function (setting, zTreeTools) {
2158                 zTreeTools.checkNode = function (node, checked, checkTypeFlag, callbackFlag) {
2159                     var nodeChecked = data.nodeChecked(setting, node);
2160                     if (node.chkDisabled === true) return;
2161                     if (checked !== true && checked !== false) {
2162                         checked = !nodeChecked;
2163                     }
2164                     callbackFlag = !!callbackFlag;
2165
2166                     if (nodeChecked === checked && !checkTypeFlag) {
2167                         return;
2168                     } else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) {
2169                         return;
2170                     }
2171                     if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) {
2172                         data.nodeChecked(setting, node, checked);
2173                         var checkObj = $$(node, consts.id.CHECK, this.setting);
2174                         if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node);
2175                         view.setChkClass(this.setting, checkObj, node);
2176                         view.repairParentChkClassWithSelf(this.setting, node);
2177                         if (callbackFlag) {
2178                             this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]);
2179                         }
2180                     }
2181                 }
2182
2183                 zTreeTools.checkAllNodes = function (checked) {
2184                     view.repairAllChk(this.setting, !!checked);
2185                 }
2186
2187                 zTreeTools.getCheckedNodes = function (checked) {
2188                     var checked = (checked !== false);
2189                     var children = data.nodeChildren(setting, data.getRoot(this.setting));
2190                     return data.getTreeCheckedNodes(this.setting, children, checked);
2191                 }
2192
2193                 zTreeTools.getChangeCheckedNodes = function () {
2194                     var children = data.nodeChildren(setting, data.getRoot(this.setting));
2195                     return data.getTreeChangeCheckedNodes(this.setting, children);
2196                 }
2197
2198                 zTreeTools.setChkDisabled = function (node, disabled, inheritParent, inheritChildren) {
2199                     disabled = !!disabled;
2200                     inheritParent = !!inheritParent;
2201                     inheritChildren = !!inheritChildren;
2202                     view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren);
2203                     view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent);
2204                 }
2205
2206                 var _updateNode = zTreeTools.updateNode;
2207                 zTreeTools.updateNode = function (node, checkTypeFlag) {
2208                     if (_updateNode) _updateNode.apply(zTreeTools, arguments);
2209                     if (!node || !this.setting.check.enable) return;
2210                     var nObj = $$(node, this.setting);
2211                     if (nObj.get(0) && tools.uCanDo(this.setting)) {
2212                         var checkObj = $$(node, consts.id.CHECK, this.setting);
2213                         if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node);
2214                         view.setChkClass(this.setting, checkObj, node);
2215                         view.repairParentChkClassWithSelf(this.setting, node);
2216                     }
2217                 }
2218             },
2219             //method of operate data
2220             _data = {
2221                 getRadioCheckedList: function (setting) {
2222                     var checkedList = data.getRoot(setting).radioCheckedList;
2223                     for (var i = 0, j = checkedList.length; i < j; i++) {
2224                         if (!data.getNodeCache(setting, checkedList[i].tId)) {
2225                             checkedList.splice(i, 1);
2226                             i--;
2227                             j--;
2228                         }
2229                     }
2230                     return checkedList;
2231                 },
2232                 getCheckStatus: function (setting, node) {
2233                     if (!setting.check.enable || node.nocheck || node.chkDisabled) return null;
2234                     var checked = data.nodeChecked(setting, node),
2235                         r = {
2236                             checked: checked,
2237                             half: node.halfCheck ? node.halfCheck : (setting.check.chkStyle == consts.radio.STYLE ? (node.check_Child_State === 2) : (checked ? (node.check_Child_State > -1 && node.check_Child_State < 2) : (node.check_Child_State > 0)))
2238                         };
2239                     return r;
2240                 },
2241                 getTreeCheckedNodes: function (setting, nodes, checked, results) {
2242                     if (!nodes) return [];
2243                     var onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL);
2244                     results = !results ? [] : results;
2245                     for (var i = 0, l = nodes.length; i < l; i++) {
2246                         var node = nodes[i];
2247                         var children = data.nodeChildren(setting, node);
2248                         var nodeChecked = data.nodeChecked(setting, node);
2249                         if (node.nocheck !== true && node.chkDisabled !== true && nodeChecked == checked) {
2250                             results.push(node);
2251                             if (onlyOne) {
2252                                 break;
2253                             }
2254                         }
2255                         data.getTreeCheckedNodes(setting, children, checked, results);
2256                         if (onlyOne && results.length > 0) {
2257                             break;
2258                         }
2259                     }
2260                     return results;
2261                 },
2262                 getTreeChangeCheckedNodes: function (setting, nodes, results) {
2263                     if (!nodes) return [];
2264                     results = !results ? [] : results;
2265                     for (var i = 0, l = nodes.length; i < l; i++) {
2266                         var node = nodes[i];
2267                         var children = data.nodeChildren(setting, node);
2268                         var nodeChecked = data.nodeChecked(setting, node);
2269                         if (node.nocheck !== true && node.chkDisabled !== true && nodeChecked != node.checkedOld) {
2270                             results.push(node);
2271                         }
2272                         data.getTreeChangeCheckedNodes(setting, children, results);
2273                     }
2274                     return results;
2275                 },
2276                 makeChkFlag: function (setting, node) {
2277                     if (!node) return;
2278                     var chkFlag = -1;
2279                     var children = data.nodeChildren(setting, node);
2280                     if (children) {
2281                         for (var i = 0, l = children.length; i < l; i++) {
2282                             var cNode = children[i];
2283                             var nodeChecked = data.nodeChecked(setting, cNode);
2284                             var tmp = -1;
2285                             if (setting.check.chkStyle == consts.radio.STYLE) {
2286                                 if (cNode.nocheck === true || cNode.chkDisabled === true) {
2287                                     tmp = cNode.check_Child_State;
2288                                 } else if (cNode.halfCheck === true) {
2289                                     tmp = 2;
2290                                 } else if (nodeChecked) {
2291                                     tmp = 2;
2292                                 } else {
2293                                     tmp = cNode.check_Child_State > 0 ? 2 : 0;
2294                                 }
2295                                 if (tmp == 2) {
2296                                     chkFlag = 2;
2297                                     break;
2298                                 } else if (tmp == 0) {
2299                                     chkFlag = 0;
2300                                 }
2301                             } else if (setting.check.chkStyle == consts.checkbox.STYLE) {
2302                                 if (cNode.nocheck === true || cNode.chkDisabled === true) {
2303                                     tmp = cNode.check_Child_State;
2304                                 } else if (cNode.halfCheck === true) {
2305                                     tmp = 1;
2306                                 } else if (nodeChecked) {
2307                                     tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1;
2308                                 } else {
2309                                     tmp = (cNode.check_Child_State > 0) ? 1 : 0;
2310                                 }
2311                                 if (tmp === 1) {
2312                                     chkFlag = 1;
2313                                     break;
2314                                 } else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) {
2315                                     chkFlag = 1;
2316                                     break;
2317                                 } else if (chkFlag === 2 && tmp > -1 && tmp < 2) {
2318                                     chkFlag = 1;
2319                                     break;
2320                                 } else if (tmp > -1) {
2321                                     chkFlag = tmp;
2322                                 }
2323                             }
2324                         }
2325                     }
2326                     node.check_Child_State = chkFlag;
2327                 }
2328             },
2329             //method of event proxy
2330             _event = {},
2331             //method of event handler
2332             _handler = {
2333                 onCheckNode: function (event, node) {
2334                     if (node.chkDisabled === true) return false;
2335                     var setting = data.getSetting(event.data.treeId);
2336                     if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true;
2337                     var nodeChecked = data.nodeChecked(setting, node);
2338                     data.nodeChecked(setting, node, !nodeChecked);
2339                     view.checkNodeRelation(setting, node);
2340                     var checkObj = $$(node, consts.id.CHECK, setting);
2341                     view.setChkClass(setting, checkObj, node);
2342                     view.repairParentChkClassWithSelf(setting, node);
2343                     setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]);
2344                     return true;
2345                 },
2346                 onMouseoverCheck: function (event, node) {
2347                     if (node.chkDisabled === true) return false;
2348                     var setting = data.getSetting(event.data.treeId),
2349                         checkObj = $$(node, consts.id.CHECK, setting);
2350                     node.check_Focus = true;
2351                     view.setChkClass(setting, checkObj, node);
2352                     return true;
2353                 },
2354                 onMouseoutCheck: function (event, node) {
2355                     if (node.chkDisabled === true) return false;
2356                     var setting = data.getSetting(event.data.treeId),
2357                         checkObj = $$(node, consts.id.CHECK, setting);
2358                     node.check_Focus = false;
2359                     view.setChkClass(setting, checkObj, node);
2360                     return true;
2361                 }
2362             },
2363             //method of tools for zTree
2364             _tools = {},
2365             //method of operate ztree dom
2366             _view = {
2367                 checkNodeRelation: function (setting, node) {
2368                     var pNode, i, l,
2369                         r = consts.radio;
2370                     var nodeChecked = data.nodeChecked(setting, node);
2371                     if (setting.check.chkStyle == r.STYLE) {
2372                         var checkedList = data.getRadioCheckedList(setting);
2373                         if (nodeChecked) {
2374                             if (setting.check.radioType == r.TYPE_ALL) {
2375                                 for (i = checkedList.length - 1; i >= 0; i--) {
2376                                     pNode = checkedList[i];
2377                                     var pNodeChecked = data.nodeChecked(setting, pNode);
2378                                     if (pNodeChecked && pNode != node) {
2379                                         data.nodeChecked(setting, pNode, false);
2380                                         checkedList.splice(i, 1);
2381
2382                                         view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode);
2383                                         if (pNode.parentTId != node.parentTId) {
2384                                             view.repairParentChkClassWithSelf(setting, pNode);
2385                                         }
2386                                     }
2387                                 }
2388                                 checkedList.push(node);
2389                             } else {
2390                                 var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting);
2391                                 var children = data.nodeChildren(setting, parentNode);
2392                                 for (i = 0, l = children.length; i < l; i++) {
2393                                     pNode = children[i];
2394                                     var pNodeChecked = data.nodeChecked(setting, pNode);
2395                                     if (pNodeChecked && pNode != node) {
2396                                         data.nodeChecked(setting, pNode, false);
2397                                         view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode);
2398                                     }
2399                                 }
2400                             }
2401                         } else if (setting.check.radioType == r.TYPE_ALL) {
2402                             for (i = 0, l = checkedList.length; i < l; i++) {
2403                                 if (node == checkedList[i]) {
2404                                     checkedList.splice(i, 1);
2405                                     break;
2406                                 }
2407                             }
2408                         }
2409
2410                     } else {
2411                         var children = data.nodeChildren(setting, node);
2412                         if (nodeChecked && (!children || children.length == 0 || setting.check.chkboxType.Y.indexOf("s") > -1)) {
2413                             view.setSonNodeCheckBox(setting, node, true);
2414                         }
2415                         if (!nodeChecked && (!children || children.length == 0 || setting.check.chkboxType.N.indexOf("s") > -1)) {
2416                             view.setSonNodeCheckBox(setting, node, false);
2417                         }
2418                         if (nodeChecked && setting.check.chkboxType.Y.indexOf("p") > -1) {
2419                             view.setParentNodeCheckBox(setting, node, true);
2420                         }
2421                         if (!nodeChecked && setting.check.chkboxType.N.indexOf("p") > -1) {
2422                             view.setParentNodeCheckBox(setting, node, false);
2423                         }
2424                     }
2425                 },
2426                 makeChkClass: function (setting, node) {
2427                     var c = consts.checkbox, r = consts.radio,
2428                         fullStyle = "";
2429                     var nodeChecked = data.nodeChecked(setting, node);
2430                     if (node.chkDisabled === true) {
2431                         fullStyle = c.DISABLED;
2432                     } else if (node.halfCheck) {
2433                         fullStyle = c.PART;
2434                     } else if (setting.check.chkStyle == r.STYLE) {
2435                         fullStyle = (node.check_Child_State < 1) ? c.FULL : c.PART;
2436                     } else {
2437                         fullStyle = nodeChecked ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL : c.PART) : ((node.check_Child_State < 1) ? c.FULL : c.PART);
2438                     }
2439                     var chkName = setting.check.chkStyle + "_" + (nodeChecked ? c.TRUE : c.FALSE) + "_" + fullStyle;
2440                     chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName;
2441                     return consts.className.BUTTON + " " + c.DEFAULT + " " + chkName;
2442                 },
2443                 repairAllChk: function (setting, checked) {
2444                     if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) {
2445                         var root = data.getRoot(setting);
2446                         var children = data.nodeChildren(setting, root);
2447                         for (var i = 0, l = children.length; i < l; i++) {
2448                             var node = children[i];
2449                             if (node.nocheck !== true && node.chkDisabled !== true) {
2450                                 data.nodeChecked(setting, node, checked);
2451                             }
2452                             view.setSonNodeCheckBox(setting, node, checked);
2453                         }
2454                     }
2455                 },
2456                 repairChkClass: function (setting, node) {
2457                     if (!node) return;
2458                     data.makeChkFlag(setting, node);
2459                     if (node.nocheck !== true) {
2460                         var checkObj = $$(node, consts.id.CHECK, setting);
2461                         view.setChkClass(setting, checkObj, node);
2462                     }
2463                 },
2464                 repairParentChkClass: function (setting, node) {
2465                     if (!node || !node.parentTId) return;
2466                     var pNode = node.getParentNode();
2467                     view.repairChkClass(setting, pNode);
2468                     view.repairParentChkClass(setting, pNode);
2469                 },
2470                 repairParentChkClassWithSelf: function (setting, node) {
2471                     if (!node) return;
2472                     var children = data.nodeChildren(setting, node);
2473                     if (children && children.length > 0) {
2474                         view.repairParentChkClass(setting, children[0]);
2475                     } else {
2476                         view.repairParentChkClass(setting, node);
2477                     }
2478                 },
2479                 repairSonChkDisabled: function (setting, node, chkDisabled, inherit) {
2480                     if (!node) return;
2481                     if (node.chkDisabled != chkDisabled) {
2482                         node.chkDisabled = chkDisabled;
2483                     }
2484                     view.repairChkClass(setting, node);
2485                     var children = data.nodeChildren(setting, node);
2486                     if (children && inherit) {
2487                         for (var i = 0, l = children.length; i < l; i++) {
2488                             var sNode = children[i];
2489                             view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit);
2490                         }
2491                     }
2492                 },
2493                 repairParentChkDisabled: function (setting, node, chkDisabled, inherit) {
2494                     if (!node) return;
2495                     if (node.chkDisabled != chkDisabled && inherit) {
2496                         node.chkDisabled = chkDisabled;
2497                     }
2498                     view.repairChkClass(setting, node);
2499                     view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit);
2500                 },
2501                 setChkClass: function (setting, obj, node) {
2502                     if (!obj) return;
2503                     if (node.nocheck === true) {
2504                         obj.hide();
2505                     } else {
2506                         obj.show();
2507                     }
2508                     obj.attr('class', view.makeChkClass(setting, node));
2509                 },
2510                 setParentNodeCheckBox: function (setting, node, value, srcNode) {
2511                     var checkObj = $$(node, consts.id.CHECK, setting);
2512                     if (!srcNode) srcNode = node;
2513                     data.makeChkFlag(setting, node);
2514                     if (node.nocheck !== true && node.chkDisabled !== true) {
2515                         data.nodeChecked(setting, node, value);
2516                         view.setChkClass(setting, checkObj, node);
2517                         if (setting.check.autoCheckTrigger && node != srcNode) {
2518                             setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]);
2519                         }
2520                     }
2521                     if (node.parentTId) {
2522                         var pSign = true;
2523                         if (!value) {
2524                             var pNodes = data.nodeChildren(setting, node.getParentNode());
2525                             for (var i = 0, l = pNodes.length; i < l; i++) {
2526                                 var pNode = pNodes[i];
2527                                 var nodeChecked = data.nodeChecked(setting, pNode);
2528                                 if ((pNode.nocheck !== true && pNode.chkDisabled !== true && nodeChecked)
2529                                     || ((pNode.nocheck === true || pNode.chkDisabled === true) && pNode.check_Child_State > 0)) {
2530                                     pSign = false;
2531                                     break;
2532                                 }
2533                             }
2534                         }
2535                         if (pSign) {
2536                             view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode);
2537                         }
2538                     }
2539                 },
2540                 setSonNodeCheckBox: function (setting, node, value, srcNode) {
2541                     if (!node) return;
2542                     var checkObj = $$(node, consts.id.CHECK, setting);
2543                     if (!srcNode) srcNode = node;
2544
2545                     var hasDisable = false;
2546                     var children = data.nodeChildren(setting, node);
2547                     if (children) {
2548                         for (var i = 0, l = children.length; i < l; i++) {
2549                             var sNode = children[i];
2550                             view.setSonNodeCheckBox(setting, sNode, value, srcNode);
2551                             if (sNode.chkDisabled === true) hasDisable = true;
2552                         }
2553                     }
2554
2555                     if (node != data.getRoot(setting) && node.chkDisabled !== true) {
2556                         if (hasDisable && node.nocheck !== true) {
2557                             data.makeChkFlag(setting, node);
2558                         }
2559                         if (node.nocheck !== true && node.chkDisabled !== true) {
2560                             data.nodeChecked(setting, node, value);
2561                             if (!hasDisable) node.check_Child_State = (children && children.length > 0) ? (value ? 2 : 0) : -1;
2562                         } else {
2563                             node.check_Child_State = -1;
2564                         }
2565                         view.setChkClass(setting, checkObj, node);
2566                         if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) {
2567                             setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]);
2568                         }
2569                     }
2570
2571                 }
2572             },
2573
2574             _z = {
2575                 tools: _tools,
2576                 view: _view,
2577                 event: _event,
2578                 data: _data
2579             };
2580         $.extend(true, $.fn.zTree.consts, _consts);
2581         $.extend(true, $.fn.zTree._z, _z);
2582
2583         var zt = $.fn.zTree,
2584             tools = zt._z.tools,
2585             consts = zt.consts,
2586             view = zt._z.view,
2587             data = zt._z.data,
2588             event = zt._z.event,
2589             $$ = tools.$;
2590
2591         data.nodeChecked = function (setting, node, newChecked) {
2592             if (!node) {
2593                 return false;
2594             }
2595             var key = setting.data.key.checked;
2596             if (typeof newChecked !== 'undefined') {
2597                 if (typeof newChecked === "string") {
2598                     newChecked = tools.eqs(newChecked, "true");
2599                 }
2600                 newChecked = !!newChecked;
2601                 node[key] = newChecked;
2602             } else if (typeof node[key] == "string") {
2603                 node[key] = tools.eqs(node[key], "true");
2604             } else {
2605                 node[key] = !!node[key];
2606             }
2607             return node[key];
2608         };
2609
2610         data.exSetting(_setting);
2611         data.addInitBind(_bindEvent);
2612         data.addInitUnBind(_unbindEvent);
2613         data.addInitCache(_initCache);
2614         data.addInitNode(_initNode);
2615         data.addInitProxy(_eventProxy, true);
2616         data.addInitRoot(_initRoot);
2617         data.addBeforeA(_beforeA);
2618         data.addZTreeTools(_zTreeTools);
2619
2620         var _createNodes = view.createNodes;
2621         view.createNodes = function (setting, level, nodes, parentNode, index) {
2622             if (_createNodes) _createNodes.apply(view, arguments);
2623             if (!nodes) return;
2624             view.repairParentChkClassWithSelf(setting, parentNode);
2625         }
2626         var _removeNode = view.removeNode;
2627         view.removeNode = function (setting, node) {
2628             var parentNode = node.getParentNode();
2629             if (_removeNode) _removeNode.apply(view, arguments);
2630             if (!node || !parentNode) return;
2631             view.repairChkClass(setting, parentNode);
2632             view.repairParentChkClass(setting, parentNode);
2633         }
2634
2635         var _appendNodes = view.appendNodes;
2636         view.appendNodes = function (setting, level, nodes, parentNode, index, initFlag, openFlag) {
2637             var html = "";
2638             if (_appendNodes) {
2639                 html = _appendNodes.apply(view, arguments);
2640             }
2641             if (parentNode) {
2642                 data.makeChkFlag(setting, parentNode);
2643             }
2644             return html;
2645         }
2646     })(jQuery);
2647     /*
2648  * JQuery zTree exedit v3.5.40
2649  * http://treejs.cn/
2650  *
2651  * Copyright (c) 2010 Hunter.z
2652  *
2653  * Licensed same as jquery - MIT License
2654  * http://www.opensource.org/licenses/mit-license.php
2655  *
2656  * email: hunter.z@263.net
2657  * Date: 2019-01-18
2658  */
2659     (function ($) {
2660         //default consts of exedit
2661         var _consts = {
2662                 event: {
2663                     DRAG: "ztree_drag",
2664                     DROP: "ztree_drop",
2665                     RENAME: "ztree_rename",
2666                     DRAGMOVE: "ztree_dragmove"
2667                 },
2668                 id: {
2669                     EDIT: "_edit",
2670                     INPUT: "_input",
2671                     REMOVE: "_remove"
2672                 },
2673                 move: {
2674                     TYPE_INNER: "inner",
2675                     TYPE_PREV: "prev",
2676                     TYPE_NEXT: "next"
2677                 },
2678                 node: {
2679                     CURSELECTED_EDIT: "curSelectedNode_Edit",
2680                     TMPTARGET_TREE: "tmpTargetzTree",
2681                     TMPTARGET_NODE: "tmpTargetNode"
2682                 }
2683             },
2684             //default setting of exedit
2685             _setting = {
2686                 edit: {
2687                     enable: false,
2688                     editNameSelectAll: false,
2689                     showRemoveBtn: true,
2690                     showRenameBtn: true,
2691                     removeTitle: "remove",
2692                     renameTitle: "rename",
2693                     drag: {
2694                         autoExpandTrigger: false,
2695                         isCopy: true,
2696                         isMove: true,
2697                         prev: true,
2698                         next: true,
2699                         inner: true,
2700                         minMoveSize: 5,
2701                         borderMax: 10,
2702                         borderMin: -5,
2703                         maxShowNodeNum: 5,
2704                         autoOpenTime: 500
2705                     }
2706                 },
2707                 view: {
2708                     addHoverDom: null,
2709                     removeHoverDom: null
2710                 },
2711                 callback: {
2712                     beforeDrag: null,
2713                     beforeDragOpen: null,
2714                     beforeDrop: null,
2715                     beforeEditName: null,
2716                     beforeRename: null,
2717                     onDrag: null,
2718                     onDragMove: null,
2719                     onDrop: null,
2720                     onRename: null
2721                 }
2722             },
2723             //default root of exedit
2724             _initRoot = function (setting) {
2725                 var r = data.getRoot(setting), rs = data.getRoots();
2726                 r.curEditNode = null;
2727                 r.curEditInput = null;
2728                 r.curHoverNode = null;
2729                 r.dragFlag = 0;
2730                 r.dragNodeShowBefore = [];
2731                 r.dragMaskList = new Array();
2732                 rs.showHoverDom = true;
2733             },
2734             //default cache of exedit
2735             _initCache = function (treeId) {
2736             },
2737             //default bind event of exedit
2738             _bindEvent = function (setting) {
2739                 var o = setting.treeObj;
2740                 var c = consts.event;
2741                 o.bind(c.RENAME, function (event, treeId, treeNode, isCancel) {
2742                     tools.apply(setting.callback.onRename, [event, treeId, treeNode, isCancel]);
2743                 });
2744
2745                 o.bind(c.DRAG, function (event, srcEvent, treeId, treeNodes) {
2746                     tools.apply(setting.callback.onDrag, [srcEvent, treeId, treeNodes]);
2747                 });
2748
2749                 o.bind(c.DRAGMOVE, function (event, srcEvent, treeId, treeNodes) {
2750                     tools.apply(setting.callback.onDragMove, [srcEvent, treeId, treeNodes]);
2751                 });
2752
2753                 o.bind(c.DROP, function (event, srcEvent, treeId, treeNodes, targetNode, moveType, isCopy) {
2754                     tools.apply(setting.callback.onDrop, [srcEvent, treeId, treeNodes, targetNode, moveType, isCopy]);
2755                 });
2756             },
2757             _unbindEvent = function (setting) {
2758                 var o = setting.treeObj;
2759                 var c = consts.event;
2760                 o.unbind(c.RENAME);
2761                 o.unbind(c.DRAG);
2762                 o.unbind(c.DRAGMOVE);
2763                 o.unbind(c.DROP);
2764             },
2765             //default event proxy of exedit
2766             _eventProxy = function (e) {
2767                 var target = e.target,
2768                     setting = data.getSetting(e.data.treeId),
2769                     relatedTarget = e.relatedTarget,
2770                     tId = "", node = null,
2771                     nodeEventType = "", treeEventType = "",
2772                     nodeEventCallback = null, treeEventCallback = null,
2773                     tmp = null;
2774
2775                 if (tools.eqs(e.type, "mouseover")) {
2776                     tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]);
2777                     if (tmp) {
2778                         tId = tools.getNodeMainDom(tmp).id;
2779                         nodeEventType = "hoverOverNode";
2780                     }
2781                 } else if (tools.eqs(e.type, "mouseout")) {
2782                     tmp = tools.getMDom(setting, relatedTarget, [{tagName: "a", attrName: "treeNode" + consts.id.A}]);
2783                     if (!tmp) {
2784                         tId = "remove";
2785                         nodeEventType = "hoverOutNode";
2786                     }
2787                 } else if (tools.eqs(e.type, "mousedown")) {
2788                     tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]);
2789                     if (tmp) {
2790                         tId = tools.getNodeMainDom(tmp).id;
2791                         nodeEventType = "mousedownNode";
2792                     }
2793                 }
2794                 if (tId.length > 0) {
2795                     node = data.getNodeCache(setting, tId);
2796                     switch (nodeEventType) {
2797                         case "mousedownNode" :
2798                             nodeEventCallback = _handler.onMousedownNode;
2799                             break;
2800                         case "hoverOverNode" :
2801                             nodeEventCallback = _handler.onHoverOverNode;
2802                             break;
2803                         case "hoverOutNode" :
2804                             nodeEventCallback = _handler.onHoverOutNode;
2805                             break;
2806                     }
2807                 }
2808                 var proxyResult = {
2809                     stop: false,
2810                     node: node,
2811                     nodeEventType: nodeEventType,
2812                     nodeEventCallback: nodeEventCallback,
2813                     treeEventType: treeEventType,
2814                     treeEventCallback: treeEventCallback
2815                 };
2816                 return proxyResult
2817             },
2818             //default init node of exedit
2819             _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) {
2820                 if (!n) return;
2821                 n.isHover = false;
2822                 n.editNameFlag = false;
2823             },
2824             //update zTreeObj, add method of edit
2825             _zTreeTools = function (setting, zTreeTools) {
2826                 zTreeTools.cancelEditName = function (newName) {
2827                     var root = data.getRoot(this.setting);
2828                     if (!root.curEditNode) return;
2829                     view.cancelCurEditNode(this.setting, newName ? newName : null, true);
2830                 }
2831                 zTreeTools.copyNode = function (targetNode, node, moveType, isSilent) {
2832                     if (!node) return null;
2833                     var isParent = data.nodeIsParent(setting, targetNode);
2834                     if (targetNode && !isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) return null;
2835                     var _this = this,
2836                         newNode = tools.clone(node);
2837                     if (!targetNode) {
2838                         targetNode = null;
2839                         moveType = consts.move.TYPE_INNER;
2840                     }
2841                     if (moveType == consts.move.TYPE_INNER) {
2842                         function copyCallback() {
2843                             view.addNodes(_this.setting, targetNode, -1, [newNode], isSilent);
2844                         }
2845
2846                         if (tools.canAsync(this.setting, targetNode)) {
2847                             view.asyncNode(this.setting, targetNode, isSilent, copyCallback);
2848                         } else {
2849                             copyCallback();
2850                         }
2851                     } else {
2852                         view.addNodes(this.setting, targetNode.parentNode, -1, [newNode], isSilent);
2853                         view.moveNode(this.setting, targetNode, newNode, moveType, false, isSilent);
2854                     }
2855                     return newNode;
2856                 }
2857                 zTreeTools.editName = function (node) {
2858                     if (!node || !node.tId || node !== data.getNodeCache(this.setting, node.tId)) return;
2859                     if (node.parentTId) view.expandCollapseParentNode(this.setting, node.getParentNode(), true);
2860                     view.editNode(this.setting, node)
2861                 }
2862                 zTreeTools.moveNode = function (targetNode, node, moveType, isSilent) {
2863                     if (!node) return node;
2864                     var isParent = data.nodeIsParent(setting, targetNode);
2865                     if (targetNode && !isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) {
2866                         return null;
2867                     } else if (targetNode && ((node.parentTId == targetNode.tId && moveType == consts.move.TYPE_INNER) || $$(node, this.setting).find("#" + targetNode.tId).length > 0)) {
2868                         return null;
2869                     } else if (!targetNode) {
2870                         targetNode = null;
2871                     }
2872                     var _this = this;
2873
2874                     function moveCallback() {
2875                         view.moveNode(_this.setting, targetNode, node, moveType, false, isSilent);
2876                     }
2877
2878                     if (tools.canAsync(this.setting, targetNode) && moveType === consts.move.TYPE_INNER) {
2879                         view.asyncNode(this.setting, targetNode, isSilent, moveCallback);
2880                     } else {
2881                         moveCallback();
2882                     }
2883                     return node;
2884                 }
2885                 zTreeTools.setEditable = function (editable) {
2886                     this.setting.edit.enable = editable;
2887                     return this.refresh();
2888                 }
2889             },
2890             //method of operate data
2891             _data = {
2892                 setSonNodeLevel: function (setting, parentNode, node) {
2893                     if (!node) return;
2894                     var children = data.nodeChildren(setting, node);
2895                     node.level = (parentNode) ? parentNode.level + 1 : 0;
2896                     if (!children) return;
2897                     for (var i = 0, l = children.length; i < l; i++) {
2898                         if (children[i]) data.setSonNodeLevel(setting, node, children[i]);
2899                     }
2900                 }
2901             },
2902             //method of event proxy
2903             _event = {},
2904             //method of event handler
2905             _handler = {
2906                 onHoverOverNode: function (event, node) {
2907                     var setting = data.getSetting(event.data.treeId),
2908                         root = data.getRoot(setting);
2909                     if (root.curHoverNode != node) {
2910                         _handler.onHoverOutNode(event);
2911                     }
2912                     root.curHoverNode = node;
2913                     view.addHoverDom(setting, node);
2914                 },
2915                 onHoverOutNode: function (event, node) {
2916                     var setting = data.getSetting(event.data.treeId),
2917                         root = data.getRoot(setting);
2918                     if (root.curHoverNode && !data.isSelectedNode(setting, root.curHoverNode)) {
2919                         view.removeTreeDom(setting, root.curHoverNode);
2920                         root.curHoverNode = null;
2921                     }
2922                 },
2923                 onMousedownNode: function (eventMouseDown, _node) {
2924                     var i, l,
2925                         setting = data.getSetting(eventMouseDown.data.treeId),
2926                         root = data.getRoot(setting), roots = data.getRoots();
2927                     //right click can't drag & drop
2928                     if (eventMouseDown.button == 2 || !setting.edit.enable || (!setting.edit.drag.isCopy && !setting.edit.drag.isMove)) return true;
2929
2930                     //input of edit node name can't drag & drop
2931                     var target = eventMouseDown.target,
2932                         _nodes = data.getRoot(setting).curSelectedList,
2933                         nodes = [];
2934                     if (!data.isSelectedNode(setting, _node)) {
2935                         nodes = [_node];
2936                     } else {
2937                         for (i = 0, l = _nodes.length; i < l; i++) {
2938                             if (_nodes[i].editNameFlag && tools.eqs(target.tagName, "input") && target.getAttribute("treeNode" + consts.id.INPUT) !== null) {
2939                                 return true;
2940                             }
2941                             nodes.push(_nodes[i]);
2942                             if (nodes[0].parentTId !== _nodes[i].parentTId) {
2943                                 nodes = [_node];
2944                                 break;
2945                             }
2946                         }
2947                     }
2948
2949                     view.editNodeBlur = true;
2950                     view.cancelCurEditNode(setting);
2951
2952                     var doc = $(setting.treeObj.get(0).ownerDocument),
2953                         body = $(setting.treeObj.get(0).ownerDocument.body), curNode, tmpArrow, tmpTarget,
2954                         isOtherTree = false,
2955                         targetSetting = setting,
2956                         sourceSetting = setting,
2957                         preNode, nextNode,
2958                         preTmpTargetNodeId = null,
2959                         preTmpMoveType = null,
2960                         tmpTargetNodeId = null,
2961                         moveType = consts.move.TYPE_INNER,
2962                         mouseDownX = eventMouseDown.clientX,
2963                         mouseDownY = eventMouseDown.clientY,
2964                         startTime = (new Date()).getTime();
2965
2966                     if (tools.uCanDo(setting)) {
2967                         doc.bind("mousemove", _docMouseMove);
2968                     }
2969
2970                     function _docMouseMove(event) {
2971                         //avoid start drag after click node
2972                         if (root.dragFlag == 0 && Math.abs(mouseDownX - event.clientX) < setting.edit.drag.minMoveSize
2973                             && Math.abs(mouseDownY - event.clientY) < setting.edit.drag.minMoveSize) {
2974                             return true;
2975                         }
2976                         var i, l, tmpNode, tmpDom, tmpNodes;
2977                         body.css("cursor", "pointer");
2978
2979                         if (root.dragFlag == 0) {
2980                             if (tools.apply(setting.callback.beforeDrag, [setting.treeId, nodes], true) == false) {
2981                                 _docMouseUp(event);
2982                                 return true;
2983                             }
2984
2985                             for (i = 0, l = nodes.length; i < l; i++) {
2986                                 if (i == 0) {
2987                                     root.dragNodeShowBefore = [];
2988                                 }
2989                                 tmpNode = nodes[i];
2990                                 if (data.nodeIsParent(setting, tmpNode) && tmpNode.open) {
2991                                     view.expandCollapseNode(setting, tmpNode, !tmpNode.open);
2992                                     root.dragNodeShowBefore[tmpNode.tId] = true;
2993                                 } else {
2994                                     root.dragNodeShowBefore[tmpNode.tId] = false;
2995                                 }
2996                             }
2997
2998                             root.dragFlag = 1;
2999                             roots.showHoverDom = false;
3000                             tools.showIfameMask(setting, true);
3001
3002                             //sort
3003                             var isOrder = true, lastIndex = -1;
3004                             if (nodes.length > 1) {
3005                                 var pNodes = nodes[0].parentTId ? data.nodeChildren(setting, nodes[0].getParentNode()) : data.getNodes(setting);
3006                                 tmpNodes = [];
3007                                 for (i = 0, l = pNodes.length; i < l; i++) {
3008                                     if (root.dragNodeShowBefore[pNodes[i].tId] !== undefined) {
3009                                         if (isOrder && lastIndex > -1 && (lastIndex + 1) !== i) {
3010                                             isOrder = false;
3011                                         }
3012                                         tmpNodes.push(pNodes[i]);
3013                                         lastIndex = i;
3014                                     }
3015                                     if (nodes.length === tmpNodes.length) {
3016                                         nodes = tmpNodes;
3017                                         break;
3018                                     }
3019                                 }
3020                             }
3021                             if (isOrder) {
3022                                 preNode = nodes[0].getPreNode();
3023                                 nextNode = nodes[nodes.length - 1].getNextNode();
3024                             }
3025
3026                             //set node in selected
3027                             curNode = $$("<ul class='zTreeDragUL'></ul>", setting);
3028                             for (i = 0, l = nodes.length; i < l; i++) {
3029                                 tmpNode = nodes[i];
3030                                 tmpNode.editNameFlag = false;
3031                                 view.selectNode(setting, tmpNode, i > 0);
3032                                 view.removeTreeDom(setting, tmpNode);
3033
3034                                 if (i > setting.edit.drag.maxShowNodeNum - 1) {
3035                                     continue;
3036                                 }
3037
3038                                 tmpDom = $$("<li id='" + tmpNode.tId + "_tmp'></li>", setting);
3039                                 tmpDom.append($$(tmpNode, consts.id.A, setting).clone());
3040                                 tmpDom.css("padding", "0");
3041                                 tmpDom.children("#" + tmpNode.tId + consts.id.A).removeClass(consts.node.CURSELECTED);
3042                                 curNode.append(tmpDom);
3043                                 if (i == setting.edit.drag.maxShowNodeNum - 1) {
3044                                     tmpDom = $$("<li id='" + tmpNode.tId + "_moretmp'><a>  ...  </a></li>", setting);
3045                                     curNode.append(tmpDom);
3046                                 }
3047                             }
3048                             curNode.attr("id", nodes[0].tId + consts.id.UL + "_tmp");
3049                             curNode.addClass(setting.treeObj.attr("class"));
3050                             curNode.appendTo(body);
3051
3052                             tmpArrow = $$("<span class='tmpzTreeMove_arrow'></span>", setting);
3053                             tmpArrow.attr("id", "zTreeMove_arrow_tmp");
3054                             tmpArrow.appendTo(body);
3055
3056                             setting.treeObj.trigger(consts.event.DRAG, [event, setting.treeId, nodes]);
3057                         }
3058
3059                         if (root.dragFlag == 1) {
3060                             if (tmpTarget && tmpArrow.attr("id") == event.target.id && tmpTargetNodeId && (event.clientX + doc.scrollLeft() + 2) > ($("#" + tmpTargetNodeId + consts.id.A, tmpTarget).offset().left)) {
3061                                 var xT = $("#" + tmpTargetNodeId + consts.id.A, tmpTarget);
3062                                 event.target = (xT.length > 0) ? xT.get(0) : event.target;
3063                             } else if (tmpTarget) {
3064                                 tmpTarget.removeClass(consts.node.TMPTARGET_TREE);
3065                                 if (tmpTargetNodeId) $("#" + tmpTargetNodeId + consts.id.A, tmpTarget).removeClass(consts.node.TMPTARGET_NODE + "_" + consts.move.TYPE_PREV)
3066                                     .removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_NEXT).removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_INNER);
3067                             }
3068                             tmpTarget = null;
3069                             tmpTargetNodeId = null;
3070
3071                             //judge drag & drop in multi ztree
3072                             isOtherTree = false;
3073                             targetSetting = setting;
3074                             var settings = data.getSettings();
3075                             for (var s in settings) {
3076                                 if (settings[s].treeId && settings[s].edit.enable && settings[s].treeId != setting.treeId
3077                                     && (event.target.id == settings[s].treeId || $(event.target).parents("#" + settings[s].treeId).length > 0)) {
3078                                     isOtherTree = true;
3079                                     targetSetting = settings[s];
3080                                 }
3081                             }
3082
3083                             var docScrollTop = doc.scrollTop(),
3084                                 docScrollLeft = doc.scrollLeft(),
3085                                 treeOffset = targetSetting.treeObj.offset(),
3086                                 scrollHeight = targetSetting.treeObj.get(0).scrollHeight,
3087                                 scrollWidth = targetSetting.treeObj.get(0).scrollWidth,
3088                                 dTop = (event.clientY + docScrollTop - treeOffset.top),
3089                                 dBottom = (targetSetting.treeObj.height() + treeOffset.top - event.clientY - docScrollTop),
3090                                 dLeft = (event.clientX + docScrollLeft - treeOffset.left),
3091                                 dRight = (targetSetting.treeObj.width() + treeOffset.left - event.clientX - docScrollLeft),
3092                                 isTop = (dTop < setting.edit.drag.borderMax && dTop > setting.edit.drag.borderMin),
3093                                 isBottom = (dBottom < setting.edit.drag.borderMax && dBottom > setting.edit.drag.borderMin),
3094                                 isLeft = (dLeft < setting.edit.drag.borderMax && dLeft > setting.edit.drag.borderMin),
3095                                 isRight = (dRight < setting.edit.drag.borderMax && dRight > setting.edit.drag.borderMin),
3096                                 isTreeInner = dTop > setting.edit.drag.borderMin && dBottom > setting.edit.drag.borderMin && dLeft > setting.edit.drag.borderMin && dRight > setting.edit.drag.borderMin,
3097                                 isTreeTop = (isTop && targetSetting.treeObj.scrollTop() <= 0),
3098                                 isTreeBottom = (isBottom && (targetSetting.treeObj.scrollTop() + targetSetting.treeObj.height() + 10) >= scrollHeight),
3099                                 isTreeLeft = (isLeft && targetSetting.treeObj.scrollLeft() <= 0),
3100                                 isTreeRight = (isRight && (targetSetting.treeObj.scrollLeft() + targetSetting.treeObj.width() + 10) >= scrollWidth);
3101
3102                             if (event.target && tools.isChildOrSelf(event.target, targetSetting.treeId)) {
3103                                 //get node <li> dom
3104                                 var targetObj = event.target;
3105                                 while (targetObj && targetObj.tagName && !tools.eqs(targetObj.tagName, "li") && targetObj.id != targetSetting.treeId) {
3106                                     targetObj = targetObj.parentNode;
3107                                 }
3108
3109                                 var canMove = true;
3110                                 //don't move to self or children of self
3111                                 for (i = 0, l = nodes.length; i < l; i++) {
3112                                     tmpNode = nodes[i];
3113                                     if (targetObj.id === tmpNode.tId) {
3114                                         canMove = false;
3115                                         break;
3116                                     } else if ($$(tmpNode, setting).find("#" + targetObj.id).length > 0) {
3117                                         canMove = false;
3118                                         break;
3119                                     }
3120                                 }
3121                                 if (canMove && event.target && tools.isChildOrSelf(event.target, targetObj.id + consts.id.A)) {
3122                                     tmpTarget = $(targetObj);
3123                                     tmpTargetNodeId = targetObj.id;
3124                                 }
3125                             }
3126
3127                             //the mouse must be in zTree
3128                             tmpNode = nodes[0];
3129                             if (isTreeInner && tools.isChildOrSelf(event.target, targetSetting.treeId)) {
3130                                 //judge mouse move in root of ztree
3131                                 if (!tmpTarget && (event.target.id == targetSetting.treeId || isTreeTop || isTreeBottom || isTreeLeft || isTreeRight) && (isOtherTree || (!isOtherTree && tmpNode.parentTId))) {
3132                                     tmpTarget = targetSetting.treeObj;
3133                                 }
3134                                 //auto scroll top
3135                                 if (isTop) {
3136                                     targetSetting.treeObj.scrollTop(targetSetting.treeObj.scrollTop() - 10);
3137                                 } else if (isBottom) {
3138                                     targetSetting.treeObj.scrollTop(targetSetting.treeObj.scrollTop() + 10);
3139                                 }
3140                                 if (isLeft) {
3141                                     targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft() - 10);
3142                                 } else if (isRight) {
3143                                     targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft() + 10);
3144                                 }
3145                                 //auto scroll left
3146                                 if (tmpTarget && tmpTarget != targetSetting.treeObj && tmpTarget.offset().left < targetSetting.treeObj.offset().left) {
3147                                     targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft() + tmpTarget.offset().left - targetSetting.treeObj.offset().left);
3148                                 }
3149                             }
3150
3151                             curNode.css({
3152                                 "top": (event.clientY + docScrollTop + 3) + "px",
3153                                 "left": (event.clientX + docScrollLeft + 3) + "px"
3154                             });
3155
3156                             var dX = 0;
3157                             var dY = 0;
3158                             if (tmpTarget && tmpTarget.attr("id") != targetSetting.treeId) {
3159                                 var tmpTargetNode = tmpTargetNodeId == null ? null : data.getNodeCache(targetSetting, tmpTargetNodeId),
3160                                     isCopy = ((event.ctrlKey || event.metaKey) && setting.edit.drag.isMove && setting.edit.drag.isCopy) || (!setting.edit.drag.isMove && setting.edit.drag.isCopy),
3161                                     isPrev = !!(preNode && tmpTargetNodeId === preNode.tId),
3162                                     isNext = !!(nextNode && tmpTargetNodeId === nextNode.tId),
3163                                     isInner = (tmpNode.parentTId && tmpNode.parentTId == tmpTargetNodeId),
3164                                     canPrev = (isCopy || !isNext) && tools.apply(targetSetting.edit.drag.prev, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.prev),
3165                                     canNext = (isCopy || !isPrev) && tools.apply(targetSetting.edit.drag.next, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.next),
3166                                     canInner = (isCopy || !isInner) && !(targetSetting.data.keep.leaf && !data.nodeIsParent(setting, tmpTargetNode)) && tools.apply(targetSetting.edit.drag.inner, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.inner);
3167
3168                                 function clearMove() {
3169                                     tmpTarget = null;
3170                                     tmpTargetNodeId = "";
3171                                     moveType = consts.move.TYPE_INNER;
3172                                     tmpArrow.css({
3173                                         "display": "none"
3174                                     });
3175                                     if (window.zTreeMoveTimer) {
3176                                         clearTimeout(window.zTreeMoveTimer);
3177                                         window.zTreeMoveTargetNodeTId = null
3178                                     }
3179                                 }
3180
3181                                 if (!canPrev && !canNext && !canInner) {
3182                                     clearMove();
3183                                 } else {
3184                                     var tmpTargetA = $("#" + tmpTargetNodeId + consts.id.A, tmpTarget),
3185                                         tmpNextA = tmpTargetNode.isLastNode ? null : $("#" + tmpTargetNode.getNextNode().tId + consts.id.A, tmpTarget.next()),
3186                                         tmpTop = tmpTargetA.offset().top,
3187                                         tmpLeft = tmpTargetA.offset().left,
3188                                         prevPercent = canPrev ? (canInner ? 0.25 : (canNext ? 0.5 : 1)) : -1,
3189                                         nextPercent = canNext ? (canInner ? 0.75 : (canPrev ? 0.5 : 0)) : -1,
3190                                         dY_percent = (event.clientY + docScrollTop - tmpTop) / tmpTargetA.height();
3191
3192                                     if ((prevPercent == 1 || dY_percent <= prevPercent && dY_percent >= -.2) && canPrev) {
3193                                         dX = 1 - tmpArrow.width();
3194                                         dY = tmpTop - tmpArrow.height() / 2;
3195                                         moveType = consts.move.TYPE_PREV;
3196                                     } else if ((nextPercent == 0 || dY_percent >= nextPercent && dY_percent <= 1.2) && canNext) {
3197                                         dX = 1 - tmpArrow.width();
3198                                         dY = (tmpNextA == null || (data.nodeIsParent(setting, tmpTargetNode) && tmpTargetNode.open)) ? (tmpTop + tmpTargetA.height() - tmpArrow.height() / 2) : (tmpNextA.offset().top - tmpArrow.height() / 2);
3199                                         moveType = consts.move.TYPE_NEXT;
3200                                     } else if (canInner) {
3201                                         dX = 5 - tmpArrow.width();
3202                                         dY = tmpTop;
3203                                         moveType = consts.move.TYPE_INNER;
3204                                     } else {
3205                                         clearMove();
3206                                     }
3207
3208                                     if (tmpTarget) {
3209                                         tmpArrow.css({
3210                                             "display": "block",
3211                                             "top": dY + "px",
3212                                             "left": (tmpLeft + dX) + "px"
3213                                         });
3214                                         tmpTargetA.addClass(consts.node.TMPTARGET_NODE + "_" + moveType);
3215
3216                                         if (preTmpTargetNodeId != tmpTargetNodeId || preTmpMoveType != moveType) {
3217                                             startTime = (new Date()).getTime();
3218                                         }
3219                                         if (tmpTargetNode && data.nodeIsParent(setting, tmpTargetNode) && moveType == consts.move.TYPE_INNER) {
3220                                             var startTimer = true;
3221                                             if (window.zTreeMoveTimer && window.zTreeMoveTargetNodeTId !== tmpTargetNode.tId) {
3222                                                 clearTimeout(window.zTreeMoveTimer);
3223                                                 window.zTreeMoveTargetNodeTId = null;
3224                                             } else if (window.zTreeMoveTimer && window.zTreeMoveTargetNodeTId === tmpTargetNode.tId) {
3225                                                 startTimer = false;
3226                                             }
3227                                             if (startTimer) {
3228                                                 window.zTreeMoveTimer = setTimeout(function () {
3229                                                     if (moveType != consts.move.TYPE_INNER) return;
3230                                                     if (tmpTargetNode && data.nodeIsParent(setting, tmpTargetNode) && !tmpTargetNode.open && (new Date()).getTime() - startTime > targetSetting.edit.drag.autoOpenTime
3231                                                         && tools.apply(targetSetting.callback.beforeDragOpen, [targetSetting.treeId, tmpTargetNode], true)) {
3232                                                         view.switchNode(targetSetting, tmpTargetNode);
3233                                                         if (targetSetting.edit.drag.autoExpandTrigger) {
3234                                                             targetSetting.treeObj.trigger(consts.event.EXPAND, [targetSetting.treeId, tmpTargetNode]);
3235                                                         }
3236                                                     }
3237                                                 }, targetSetting.edit.drag.autoOpenTime + 50);
3238                                                 window.zTreeMoveTargetNodeTId = tmpTargetNode.tId;
3239                                             }
3240                                         }
3241                                     }
3242                                 }
3243                             } else {
3244                                 moveType = consts.move.TYPE_INNER;
3245                                 if (tmpTarget && tools.apply(targetSetting.edit.drag.inner, [targetSetting.treeId, nodes, null], !!targetSetting.edit.drag.inner)) {
3246                                     tmpTarget.addClass(consts.node.TMPTARGET_TREE);
3247                                 } else {
3248                                     tmpTarget = null;
3249                                 }
3250                                 tmpArrow.css({
3251                                     "display": "none"
3252                                 });
3253                                 if (window.zTreeMoveTimer) {
3254                                     clearTimeout(window.zTreeMoveTimer);
3255                                     window.zTreeMoveTargetNodeTId = null;
3256                                 }
3257                             }
3258                             preTmpTargetNodeId = tmpTargetNodeId;
3259                             preTmpMoveType = moveType;
3260
3261                             setting.treeObj.trigger(consts.event.DRAGMOVE, [event, setting.treeId, nodes]);
3262                         }
3263                         return false;
3264                     }
3265
3266                     doc.bind("mouseup", _docMouseUp);
3267
3268                     function _docMouseUp(event) {
3269                         if (window.zTreeMoveTimer) {
3270                             clearTimeout(window.zTreeMoveTimer);
3271                             window.zTreeMoveTargetNodeTId = null;
3272                         }
3273                         preTmpTargetNodeId = null;
3274                         preTmpMoveType = null;
3275                         doc.unbind("mousemove", _docMouseMove);
3276                         doc.unbind("mouseup", _docMouseUp);
3277                         doc.unbind("selectstart", _docSelect);
3278                         body.css("cursor", "");
3279                         if (tmpTarget) {
3280                             tmpTarget.removeClass(consts.node.TMPTARGET_TREE);
3281                             if (tmpTargetNodeId) $("#" + tmpTargetNodeId + consts.id.A, tmpTarget).removeClass(consts.node.TMPTARGET_NODE + "_" + consts.move.TYPE_PREV)
3282                                 .removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_NEXT).removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_INNER);
3283                         }
3284                         tools.showIfameMask(setting, false);
3285
3286                         roots.showHoverDom = true;
3287                         if (root.dragFlag == 0) return;
3288                         root.dragFlag = 0;
3289
3290                         var i, l, tmpNode;
3291                         for (i = 0, l = nodes.length; i < l; i++) {
3292                             tmpNode = nodes[i];
3293                             if (data.nodeIsParent(setting, tmpNode) && root.dragNodeShowBefore[tmpNode.tId] && !tmpNode.open) {
3294                                 view.expandCollapseNode(setting, tmpNode, !tmpNode.open);
3295                                 delete root.dragNodeShowBefore[tmpNode.tId];
3296                             }
3297                         }
3298
3299                         if (curNode) curNode.remove();
3300                         if (tmpArrow) tmpArrow.remove();
3301
3302                         var isCopy = ((event.ctrlKey || event.metaKey) && setting.edit.drag.isMove && setting.edit.drag.isCopy) || (!setting.edit.drag.isMove && setting.edit.drag.isCopy);
3303                         if (!isCopy && tmpTarget && tmpTargetNodeId && nodes[0].parentTId && tmpTargetNodeId == nodes[0].parentTId && moveType == consts.move.TYPE_INNER) {
3304                             tmpTarget = null;
3305                         }
3306                         if (tmpTarget) {
3307                             var dragTargetNode = tmpTargetNodeId == null ? null : data.getNodeCache(targetSetting, tmpTargetNodeId);
3308                             if (tools.apply(setting.callback.beforeDrop, [targetSetting.treeId, nodes, dragTargetNode, moveType, isCopy], true) == false) {
3309                                 view.selectNodes(sourceSetting, nodes);
3310                                 return;
3311                             }
3312                             var newNodes = isCopy ? tools.clone(nodes) : nodes;
3313
3314                             function dropCallback() {
3315                                 if (isOtherTree) {
3316                                     if (!isCopy) {
3317                                         for (var i = 0, l = nodes.length; i < l; i++) {
3318                                             view.removeNode(setting, nodes[i]);
3319                                         }
3320                                     }
3321                                     if (moveType == consts.move.TYPE_INNER) {
3322                                         view.addNodes(targetSetting, dragTargetNode, -1, newNodes);
3323                                     } else {
3324                                         view.addNodes(targetSetting, dragTargetNode.getParentNode(), moveType == consts.move.TYPE_PREV ? dragTargetNode.getIndex() : dragTargetNode.getIndex() + 1, newNodes);
3325                                     }
3326                                 } else {
3327                                     if (isCopy && moveType == consts.move.TYPE_INNER) {
3328                                         view.addNodes(targetSetting, dragTargetNode, -1, newNodes);
3329                                     } else if (isCopy) {
3330                                         view.addNodes(targetSetting, dragTargetNode.getParentNode(), moveType == consts.move.TYPE_PREV ? dragTargetNode.getIndex() : dragTargetNode.getIndex() + 1, newNodes);
3331                                     } else {
3332                                         if (moveType != consts.move.TYPE_NEXT) {
3333                                             for (i = 0, l = newNodes.length; i < l; i++) {
3334                                                 view.moveNode(targetSetting, dragTargetNode, newNodes[i], moveType, false);
3335                                             }
3336                                         } else {
3337                                             for (i = -1, l = newNodes.length - 1; i < l; l--) {
3338                                                 view.moveNode(targetSetting, dragTargetNode, newNodes[l], moveType, false);
3339                                             }
3340                                         }
3341                                     }
3342                                 }
3343                                 view.selectNodes(targetSetting, newNodes);
3344
3345                                 var a = $$(newNodes[0], setting).get(0);
3346                                 view.scrollIntoView(setting, a);
3347
3348                                 setting.treeObj.trigger(consts.event.DROP, [event, targetSetting.treeId, newNodes, dragTargetNode, moveType, isCopy]);
3349                             }
3350
3351                             if (moveType == consts.move.TYPE_INNER && tools.canAsync(targetSetting, dragTargetNode)) {
3352                                 view.asyncNode(targetSetting, dragTargetNode, false, dropCallback);
3353                             } else {
3354                                 dropCallback();
3355                             }
3356
3357                         } else {
3358                             view.selectNodes(sourceSetting, nodes);
3359                             setting.treeObj.trigger(consts.event.DROP, [event, setting.treeId, nodes, null, null, null]);
3360                         }
3361                     }
3362
3363                     doc.bind("selectstart", _docSelect);
3364
3365                     function _docSelect() {
3366                         return false;
3367                     }
3368
3369                     // 2018-03-30 FireFox has fixed this issue.
3370                     //Avoid FireFox's Bug
3371                     //If zTree Div CSS set 'overflow', so drag node outside of zTree, and event.target is error.
3372                     // if(eventMouseDown.preventDefault) {
3373                     //     eventMouseDown.preventDefault();
3374                     // }
3375                     return true;
3376                 }
3377             },
3378             //method of tools for zTree
3379             _tools = {
3380                 getAbs: function (obj) {
3381                     var oRect = obj.getBoundingClientRect(),
3382                         scrollTop = document.body.scrollTop + document.documentElement.scrollTop,
3383                         scrollLeft = document.body.scrollLeft + document.documentElement.scrollLeft;
3384                     return [oRect.left + scrollLeft, oRect.top + scrollTop];
3385                 },
3386                 inputFocus: function (inputObj) {
3387                     if (inputObj.get(0)) {
3388                         inputObj.focus();
3389                         tools.setCursorPosition(inputObj.get(0), inputObj.val().length);
3390                     }
3391                 },
3392                 inputSelect: function (inputObj) {
3393                     if (inputObj.get(0)) {
3394                         inputObj.focus();
3395                         inputObj.select();
3396                     }
3397                 },
3398                 setCursorPosition: function (obj, pos) {
3399                     if (obj.setSelectionRange) {
3400                         obj.focus();
3401                         obj.setSelectionRange(pos, pos);
3402                     } else if (obj.createTextRange) {
3403                         var range = obj.createTextRange();
3404                         range.collapse(true);
3405                         range.moveEnd('character', pos);
3406                         range.moveStart('character', pos);
3407                         range.select();
3408                     }
3409                 },
3410                 showIfameMask: function (setting, showSign) {
3411                     var root = data.getRoot(setting);
3412                     //clear full mask
3413                     while (root.dragMaskList.length > 0) {
3414                         root.dragMaskList[0].remove();
3415                         root.dragMaskList.shift();
3416                     }
3417                     if (showSign) {
3418                         //show mask
3419                         var iframeList = $$("iframe", setting);
3420                         for (var i = 0, l = iframeList.length; i < l; i++) {
3421                             var obj = iframeList.get(i),
3422                                 r = tools.getAbs(obj),
3423                                 dragMask = $$("<div id='zTreeMask_" + i + "' class='zTreeMask' style='top:" + r[1] + "px; left:" + r[0] + "px; width:" + obj.offsetWidth + "px; height:" + obj.offsetHeight + "px;'></div>", setting);
3424                             dragMask.appendTo($$("body", setting));
3425                             root.dragMaskList.push(dragMask);
3426                         }
3427                     }
3428                 }
3429             },
3430             //method of operate ztree dom
3431             _view = {
3432                 addEditBtn: function (setting, node) {
3433                     if (node.editNameFlag || $$(node, consts.id.EDIT, setting).length > 0) {
3434                         return;
3435                     }
3436                     if (!tools.apply(setting.edit.showRenameBtn, [setting.treeId, node], setting.edit.showRenameBtn)) {
3437                         return;
3438                     }
3439                     var aObj = $$(node, consts.id.A, setting),
3440                         editStr = "<span class='" + consts.className.BUTTON + " edit' id='" + node.tId + consts.id.EDIT + "' title='" + tools.apply(setting.edit.renameTitle, [setting.treeId, node], setting.edit.renameTitle) + "' treeNode" + consts.id.EDIT + " style='display:none;'></span>";
3441                     aObj.append(editStr);
3442
3443                     $$(node, consts.id.EDIT, setting).bind('click',
3444                         function () {
3445                             if (!tools.uCanDo(setting) || tools.apply(setting.callback.beforeEditName, [setting.treeId, node], true) == false) return false;
3446                             view.editNode(setting, node);
3447                             return false;
3448                         }
3449                     ).show();
3450                 },
3451                 addRemoveBtn: function (setting, node) {
3452                     if (node.editNameFlag || $$(node, consts.id.REMOVE, setting).length > 0) {
3453                         return;
3454                     }
3455                     if (!tools.apply(setting.edit.showRemoveBtn, [setting.treeId, node], setting.edit.showRemoveBtn)) {
3456                         return;
3457                     }
3458                     var aObj = $$(node, consts.id.A, setting),
3459                         removeStr = "<span class='" + consts.className.BUTTON + " remove' id='" + node.tId + consts.id.REMOVE + "' title='" + tools.apply(setting.edit.removeTitle, [setting.treeId, node], setting.edit.removeTitle) + "' treeNode" + consts.id.REMOVE + " style='display:none;'></span>";
3460                     aObj.append(removeStr);
3461
3462                     $$(node, consts.id.REMOVE, setting).bind('click',
3463                         function () {
3464                             if (!tools.uCanDo(setting) || tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return false;
3465                             view.removeNode(setting, node);
3466                             setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]);
3467                             return false;
3468                         }
3469                     ).bind('mousedown',
3470                         function (eventMouseDown) {
3471                             return true;
3472                         }
3473                     ).show();
3474                 },
3475                 addHoverDom: function (setting, node) {
3476                     if (data.getRoots().showHoverDom) {
3477                         node.isHover = true;
3478                         if (setting.edit.enable) {
3479                             view.addEditBtn(setting, node);
3480                             view.addRemoveBtn(setting, node);
3481                         }
3482                         tools.apply(setting.view.addHoverDom, [setting.treeId, node]);
3483                     }
3484                 },
3485                 cancelCurEditNode: function (setting, forceName, isCancel) {
3486                     var root = data.getRoot(setting),
3487                         node = root.curEditNode;
3488
3489                     if (node) {
3490                         var inputObj = root.curEditInput,
3491                             newName = forceName ? forceName : (isCancel ? data.nodeName(setting, node) : inputObj.val());
3492                         if (tools.apply(setting.callback.beforeRename, [setting.treeId, node, newName, isCancel], true) === false) {
3493                             return false;
3494                         }
3495                         data.nodeName(setting, node, newName);
3496                         var aObj = $$(node, consts.id.A, setting);
3497                         aObj.removeClass(consts.node.CURSELECTED_EDIT);
3498                         inputObj.unbind();
3499                         view.setNodeName(setting, node);
3500                         node.editNameFlag = false;
3501                         root.curEditNode = null;
3502                         root.curEditInput = null;
3503                         view.selectNode(setting, node, false);
3504                         setting.treeObj.trigger(consts.event.RENAME, [setting.treeId, node, isCancel]);
3505                     }
3506                     root.noSelection = true;
3507                     return true;
3508                 },
3509                 editNode: function (setting, node) {
3510                     var root = data.getRoot(setting);
3511                     view.editNodeBlur = false;
3512                     if (data.isSelectedNode(setting, node) && root.curEditNode == node && node.editNameFlag) {
3513                         setTimeout(function () {
3514                             tools.inputFocus(root.curEditInput);
3515                         }, 0);
3516                         return;
3517                     }
3518                     node.editNameFlag = true;
3519                     view.removeTreeDom(setting, node);
3520                     view.cancelCurEditNode(setting);
3521                     view.selectNode(setting, node, false);
3522                     $$(node, consts.id.SPAN, setting).html("<input type=text class='rename' id='" + node.tId + consts.id.INPUT + "' treeNode" + consts.id.INPUT + " >");
3523                     var inputObj = $$(node, consts.id.INPUT, setting);
3524                     inputObj.attr("value", data.nodeName(setting, node));
3525                     if (setting.edit.editNameSelectAll) {
3526                         tools.inputSelect(inputObj);
3527                     } else {
3528                         tools.inputFocus(inputObj);
3529                     }
3530
3531                     inputObj.bind('blur', function (event) {
3532                         if (!view.editNodeBlur) {
3533                             view.cancelCurEditNode(setting);
3534                         }
3535                     }).bind('keydown', function (event) {
3536                         if (event.keyCode == "13") {
3537                             view.editNodeBlur = true;
3538                             view.cancelCurEditNode(setting);
3539                         } else if (event.keyCode == "27") {
3540                             view.cancelCurEditNode(setting, null, true);
3541                         }
3542                     }).bind('click', function (event) {
3543                         return false;
3544                     }).bind('dblclick', function (event) {
3545                         return false;
3546                     });
3547
3548                     $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED_EDIT);
3549                     root.curEditInput = inputObj;
3550                     root.noSelection = false;
3551                     root.curEditNode = node;
3552                 },
3553                 moveNode: function (setting, targetNode, node, moveType, animateFlag, isSilent) {
3554                     var root = data.getRoot(setting);
3555                     if (targetNode == node) return;
3556                     if (setting.data.keep.leaf && targetNode && !data.nodeIsParent(setting, targetNode) && moveType == consts.move.TYPE_INNER) return;
3557                     var oldParentNode = (node.parentTId ? node.getParentNode() : root),
3558                         targetNodeIsRoot = (targetNode === null || targetNode == root);
3559                     if (targetNodeIsRoot && targetNode === null) targetNode = root;
3560                     if (targetNodeIsRoot) moveType = consts.move.TYPE_INNER;
3561                     var targetParentNode = (targetNode.parentTId ? targetNode.getParentNode() : root);
3562
3563                     if (moveType != consts.move.TYPE_PREV && moveType != consts.move.TYPE_NEXT) {
3564                         moveType = consts.move.TYPE_INNER;
3565                     }
3566
3567                     if (moveType == consts.move.TYPE_INNER) {
3568                         if (targetNodeIsRoot) {
3569                             //parentTId of root node is null
3570                             node.parentTId = null;
3571                         } else {
3572                             if (!data.nodeIsParent(setting, targetNode)) {
3573                                 data.nodeIsParent(setting, targetNode, true);
3574                                 targetNode.open = !!targetNode.open;
3575                                 view.setNodeLineIcos(setting, targetNode);
3576                             }
3577                             node.parentTId = targetNode.tId;
3578                         }
3579                     }
3580
3581                     //move node Dom
3582                     var targetObj, target_ulObj;
3583                     if (targetNodeIsRoot) {
3584                         targetObj = setting.treeObj;
3585                         target_ulObj = targetObj;
3586                     } else {
3587                         if (!isSilent && moveType == consts.move.TYPE_INNER) {
3588                             view.expandCollapseNode(setting, targetNode, true, false);
3589                         } else if (!isSilent) {
3590                             view.expandCollapseNode(setting, targetNode.getParentNode(), true, false);
3591                         }
3592                         targetObj = $$(targetNode, setting);
3593                         target_ulObj = $$(targetNode, consts.id.UL, setting);
3594                         if (!!targetObj.get(0) && !target_ulObj.get(0)) {
3595                             var ulstr = [];
3596                             view.makeUlHtml(setting, targetNode, ulstr, '');
3597                             targetObj.append(ulstr.join(''));
3598                         }
3599                         target_ulObj = $$(targetNode, consts.id.UL, setting);
3600                     }
3601                     var nodeDom = $$(node, setting);
3602                     if (!nodeDom.get(0)) {
3603                         nodeDom = view.appendNodes(setting, node.level, [node], null, -1, false, true).join('');
3604                     } else if (!targetObj.get(0)) {
3605                         nodeDom.remove();
3606                     }
3607                     if (target_ulObj.get(0) && moveType == consts.move.TYPE_INNER) {
3608                         target_ulObj.append(nodeDom);
3609                     } else if (targetObj.get(0) && moveType == consts.move.TYPE_PREV) {
3610                         targetObj.before(nodeDom);
3611                     } else if (targetObj.get(0) && moveType == consts.move.TYPE_NEXT) {
3612                         targetObj.after(nodeDom);
3613                     }
3614
3615                     //repair the data after move
3616                     var i, l,
3617                         tmpSrcIndex = -1,
3618                         tmpTargetIndex = 0,
3619                         oldNeighbor = null,
3620                         newNeighbor = null,
3621                         oldLevel = node.level;
3622                     var oldChildren = data.nodeChildren(setting, oldParentNode);
3623                     var targetParentChildren = data.nodeChildren(setting, targetParentNode);
3624                     var targetChildren = data.nodeChildren(setting, targetNode);
3625                     if (node.isFirstNode) {
3626                         tmpSrcIndex = 0;
3627                         if (oldChildren.length > 1) {
3628                             oldNeighbor = oldChildren[1];
3629                             oldNeighbor.isFirstNode = true;
3630                         }
3631                     } else if (node.isLastNode) {
3632                         tmpSrcIndex = oldChildren.length - 1;
3633                         oldNeighbor = oldChildren[tmpSrcIndex - 1];
3634                         oldNeighbor.isLastNode = true;
3635                     } else {
3636                         for (i = 0, l = oldChildren.length; i < l; i++) {
3637                             if (oldChildren[i].tId == node.tId) {
3638                                 tmpSrcIndex = i;
3639                                 break;
3640                             }
3641                         }
3642                     }
3643                     if (tmpSrcIndex >= 0) {
3644                         oldChildren.splice(tmpSrcIndex, 1);
3645                     }
3646                     if (moveType != consts.move.TYPE_INNER) {
3647                         for (i = 0, l = targetParentChildren.length; i < l; i++) {
3648                             if (targetParentChildren[i].tId == targetNode.tId) tmpTargetIndex = i;
3649                         }
3650                     }
3651                     if (moveType == consts.move.TYPE_INNER) {
3652                         if (!targetChildren) {
3653                             targetChildren = data.nodeChildren(setting, targetNode, []);
3654                         }
3655                         if (targetChildren.length > 0) {
3656                             newNeighbor = targetChildren[targetChildren.length - 1];
3657                             newNeighbor.isLastNode = false;
3658                         }
3659                         targetChildren.splice(targetChildren.length, 0, node);
3660                         node.isLastNode = true;
3661                         node.isFirstNode = (targetChildren.length == 1);
3662                     } else if (targetNode.isFirstNode && moveType == consts.move.TYPE_PREV) {
3663                         targetParentChildren.splice(tmpTargetIndex, 0, node);
3664                         newNeighbor = targetNode;
3665                         newNeighbor.isFirstNode = false;
3666                         node.parentTId = targetNode.parentTId;
3667                         node.isFirstNode = true;
3668                         node.isLastNode = false;
3669
3670                     } else if (targetNode.isLastNode && moveType == consts.move.TYPE_NEXT) {
3671                         targetParentChildren.splice(tmpTargetIndex + 1, 0, node);
3672                         newNeighbor = targetNode;
3673                         newNeighbor.isLastNode = false;
3674                         node.parentTId = targetNode.parentTId;
3675                         node.isFirstNode = false;
3676                         node.isLastNode = true;
3677
3678                     } else {
3679                         if (moveType == consts.move.TYPE_PREV) {
3680                             targetParentChildren.splice(tmpTargetIndex, 0, node);
3681                         } else {
3682                             targetParentChildren.splice(tmpTargetIndex + 1, 0, node);
3683                         }
3684                         node.parentTId = targetNode.parentTId;
3685                         node.isFirstNode = false;
3686                         node.isLastNode = false;
3687                     }
3688                     data.fixPIdKeyValue(setting, node);
3689                     data.setSonNodeLevel(setting, node.getParentNode(), node);
3690
3691                     //repair node what been moved
3692                     view.setNodeLineIcos(setting, node);
3693                     view.repairNodeLevelClass(setting, node, oldLevel);
3694
3695                     //repair node's old parentNode dom
3696                     if (!setting.data.keep.parent && oldChildren.length < 1) {
3697                         //old parentNode has no child nodes
3698                         data.nodeIsParent(setting, oldParentNode, false);
3699                         oldParentNode.open = false;
3700                         var tmp_ulObj = $$(oldParentNode, consts.id.UL, setting),
3701                             tmp_switchObj = $$(oldParentNode, consts.id.SWITCH, setting),
3702                             tmp_icoObj = $$(oldParentNode, consts.id.ICON, setting);
3703                         view.replaceSwitchClass(oldParentNode, tmp_switchObj, consts.folder.DOCU);
3704                         view.replaceIcoClass(oldParentNode, tmp_icoObj, consts.folder.DOCU);
3705                         tmp_ulObj.css("display", "none");
3706
3707                     } else if (oldNeighbor) {
3708                         //old neigbor node
3709                         view.setNodeLineIcos(setting, oldNeighbor);
3710                     }
3711
3712                     //new neigbor node
3713                     if (newNeighbor) {
3714                         view.setNodeLineIcos(setting, newNeighbor);
3715                     }
3716
3717                     //repair checkbox / radio
3718                     if (!!setting.check && setting.check.enable && view.repairChkClass) {
3719                         view.repairChkClass(setting, oldParentNode);
3720                         view.repairParentChkClassWithSelf(setting, oldParentNode);
3721                         if (oldParentNode != node.parent)
3722                             view.repairParentChkClassWithSelf(setting, node);
3723                     }
3724
3725                     //expand parents after move
3726                     if (!isSilent) {
3727                         view.expandCollapseParentNode(setting, node.getParentNode(), true, animateFlag);
3728                     }
3729                 },
3730                 removeEditBtn: function (setting, node) {
3731                     $$(node, consts.id.EDIT, setting).unbind().remove();
3732                 },
3733                 removeRemoveBtn: function (setting, node) {
3734                     $$(node, consts.id.REMOVE, setting).unbind().remove();
3735                 },
3736                 removeTreeDom: function (setting, node) {
3737                     node.isHover = false;
3738                     view.removeEditBtn(setting, node);
3739                     view.removeRemoveBtn(setting, node);
3740                     tools.apply(setting.view.removeHoverDom, [setting.treeId, node]);
3741                 },
3742                 repairNodeLevelClass: function (setting, node, oldLevel) {
3743                     if (oldLevel === node.level) return;
3744                     var liObj = $$(node, setting),
3745                         aObj = $$(node, consts.id.A, setting),
3746                         ulObj = $$(node, consts.id.UL, setting),
3747                         oldClass = consts.className.LEVEL + oldLevel,
3748                         newClass = consts.className.LEVEL + node.level;
3749                     liObj.removeClass(oldClass);
3750                     liObj.addClass(newClass);
3751                     aObj.removeClass(oldClass);
3752                     aObj.addClass(newClass);
3753                     ulObj.removeClass(oldClass);
3754                     ulObj.addClass(newClass);
3755                 },
3756                 selectNodes: function (setting, nodes) {
3757                     for (var i = 0, l = nodes.length; i < l; i++) {
3758                         view.selectNode(setting, nodes[i], i > 0);
3759                     }
3760                 }
3761             },
3762
3763             _z = {
3764                 tools: _tools,
3765                 view: _view,
3766                 event: _event,
3767                 data: _data
3768             };
3769         $.extend(true, $.fn.zTree.consts, _consts);
3770         $.extend(true, $.fn.zTree._z, _z);
3771
3772         var zt = $.fn.zTree,
3773             tools = zt._z.tools,
3774             consts = zt.consts,
3775             view = zt._z.view,
3776             data = zt._z.data,
3777             event = zt._z.event,
3778             $$ = tools.$;
3779
3780         data.exSetting(_setting);
3781         data.addInitBind(_bindEvent);
3782         data.addInitUnBind(_unbindEvent);
3783         data.addInitCache(_initCache);
3784         data.addInitNode(_initNode);
3785         data.addInitProxy(_eventProxy);
3786         data.addInitRoot(_initRoot);
3787         data.addZTreeTools(_zTreeTools);
3788
3789         var _cancelPreSelectedNode = view.cancelPreSelectedNode;
3790         view.cancelPreSelectedNode = function (setting, node) {
3791             var list = data.getRoot(setting).curSelectedList;
3792             for (var i = 0, j = list.length; i < j; i++) {
3793                 if (!node || node === list[i]) {
3794                     view.removeTreeDom(setting, list[i]);
3795                     if (node) break;
3796                 }
3797             }
3798             if (_cancelPreSelectedNode) _cancelPreSelectedNode.apply(view, arguments);
3799         }
3800
3801         var _createNodes = view.createNodes;
3802         view.createNodes = function (setting, level, nodes, parentNode, index) {
3803             if (_createNodes) {
3804                 _createNodes.apply(view, arguments);
3805             }
3806             if (!nodes) return;
3807             if (view.repairParentChkClassWithSelf) {
3808                 view.repairParentChkClassWithSelf(setting, parentNode);
3809             }
3810         }
3811
3812         var _makeNodeUrl = view.makeNodeUrl;
3813         view.makeNodeUrl = function (setting, node) {
3814             return setting.edit.enable ? null : (_makeNodeUrl.apply(view, arguments));
3815         }
3816
3817         var _removeNode = view.removeNode;
3818         view.removeNode = function (setting, node) {
3819             var root = data.getRoot(setting);
3820             if (root.curEditNode === node) root.curEditNode = null;
3821             if (_removeNode) {
3822                 _removeNode.apply(view, arguments);
3823             }
3824         }
3825
3826         var _selectNode = view.selectNode;
3827         view.selectNode = function (setting, node, addFlag) {
3828             var root = data.getRoot(setting);
3829             if (data.isSelectedNode(setting, node) && root.curEditNode == node && node.editNameFlag) {
3830                 return false;
3831             }
3832             if (_selectNode) _selectNode.apply(view, arguments);
3833             view.addHoverDom(setting, node);
3834             return true;
3835         }
3836
3837         var _uCanDo = tools.uCanDo;
3838         tools.uCanDo = function (setting, e) {
3839             var root = data.getRoot(setting);
3840             if (e && (tools.eqs(e.type, "mouseover") || tools.eqs(e.type, "mouseout") || tools.eqs(e.type, "mousedown") || tools.eqs(e.type, "mouseup"))) {
3841                 return true;
3842             }
3843             if (root.curEditNode) {
3844                 view.editNodeBlur = false;
3845                 root.curEditInput.focus();
3846             }
3847             return (!root.curEditNode) && (_uCanDo ? _uCanDo.apply(view, arguments) : true);
3848         }
3849     })(jQuery);
3850
3851     exports('zTree', $.fn.zTree);
3852 });