diff --git a/src/js/tree.js b/src/js/tree.js
index 56eb071ad51eba8cb987c6a27b00272400a56422..1c8c20a01256b68d674cefbf8325a60e0da592e3 100644
--- a/src/js/tree.js
+++ b/src/js/tree.js
@@ -12,15 +12,21 @@
var name = 'zui.tree'; // modal name
var globalId = 0;
+ function escape(unsafe) {
+ return unsafe.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');
+ }
+
// The tree modal class
var Tree = function(element, options) {
this.name = name;
this.$ = $(element);
-
+ this.$ulTmp = $('
');
this.getOptions(options);
this._init();
};
+ Tree.escape = escape;
+
var DETAULT_ACTIONS = {
sort: {
template: ''
@@ -86,55 +92,66 @@
itemConverter: null, // function(item) {}
};
- Tree.prototype.add = function(rootEle, items, expand, disabledAnimate, notStore) {
- var $e = $(rootEle), $ul, options = this.options;
- if($e.is('li')) {
- $ul = $e.children('ul');
- if(!$ul.length) {
- $ul = $('');
- $e.append($ul);
- this._initList($ul, $e);
+ Tree.prototype.add = function(ele, items, parent, $ul, $parent, isRoot) {
+ var gid = $.guid++;
+ var that = this;
+ var $e = $(ele), options = that.options, needAppendUl;
+ if(!$ul) {
+ if($e.prop('tagName') === 'UL') {
+ $ul = $e;
+ } else {
+ $ul = $e.children('ul');
+ if(!$ul.length) {
+ needAppendUl = true;
+ $ul = that.$ulTmp.clone();
+ }
+ $parent = $e;
}
- } else {
- $ul = $e;
+ }
+ if(!$parent && !isRoot) {
+ $parent = $ul.parent('li');
}
- if($ul) {
- var that = this;
- if(!Array.isArray(items)) {
- items = [items];
+ if(!Array.isArray(items)) {
+ items = [items];
+ }
+ var itemConverter = options.itemConverter;
+ var itemCreator = options.itemCreator;
+ var itemRender = options.itemRender;
+ var itemWrapper = options.itemWrapper;
+ var $itemWrapper = itemWrapper ? $(itemWrapper === true ? '' : itemWrapper) : null;
+ items.forEach(function(item, idx) {
+ if(itemConverter) item = itemConverter(item);
+ if(item.id === undefined) item.id = (parent ? (parent.id + '_') : '') + idx;
+ var $li = $('', {'data-id': item.id}).data(item);
+ var $wrapper = $itemWrapper ? $itemWrapper.clone().appendTo($li) : $li;
+ var html = '';
+ if(item.html) {
+ html = item.html;
+ } else if(itemCreator) {
+ var itemContent = itemCreator($li, item);
+ if(typeof itemContent === 'string') html = itemContent;
+ } else if(item.url) {
+ html = '' + escape(item.title || item.name) + '';
+ } else {
+ html = '' + escape(item.title || item.name) + '';
}
- var itemConverter = options.itemConverter;
- var itemCreator = options.itemCreator;
- var itemRender = options.itemRender;
- $.each(items, function(idx, item) {
- if(itemConverter) item = itemConverter(item);
- var $li = $('').data(item).appendTo($ul);
- if(item.id !== undefined) $li.attr('data-id', item.id);
- var $wrapper = options.itemWrapper ? $(options.itemWrapper === true ? '' : options.itemWrapper).appendTo($li) : $li;
- if(item.html) {
- $wrapper.html(item.html)
- } else if(itemCreator) {
- var itemContent = itemCreator($li, item);
- if(itemContent !== true && itemContent !== false) $wrapper.html(itemContent);
- } else if(item.url) {
- $wrapper.append($('', {href: item.url}).text(item.title || item.name));
- } else {
- $wrapper.append($('').text(item.title || item.name));
- }
- that._initItem($li, item.idx || idx, $ul, item);
- if(item.children && item.children.length) {
- that.add($li, item.children);
- }
- if(itemRender) {
- itemRender($li, item);
- }
- });
- this._initList($ul);
- if(expand && !$ul.hasClass('tree')) {
- that.expand($ul.parent('li'), disabledAnimate, notStore);
+ $wrapper.html(html);
+ that._initItem($li, $ul, item, null, true);
+ if(item.children && item.children.length) {
+ var $childUl = that.$ulTmp.clone().appendTo($li);
+ that.add($li, item.children, item, $childUl, $li);
+ }
+ if(itemRender) {
+ itemRender($li, item);
}
+ if(item.open) $li.addClass('open in');
+ $ul.append($li);
+ });
+ if(needAppendUl) {
+ $e.append($ul);
}
+ this._initList($ul, $parent, parent, isRoot, true);
};
Tree.prototype.reload = function(data) {
@@ -142,11 +159,8 @@
if(data) {
that.$.empty();
- that.add(that.$, data);
- }
-
- if(that.isPreserve)
- {
+ that.add(that.$, data, null, that.$, null, true);
+ } else if(that.isPreserve) {
if(that.store.time) {
that.$.find('li:not(.tree-action-item)').each(function() {
var $li= $(this);
@@ -156,28 +170,30 @@
}
};
- Tree.prototype._initList = function($list, $parentItem, idx, data) {
+ Tree.prototype._initList = function($list, $parentItem, data, isRoot, skipCheckExists) {
var that = this;
- if(!$list.hasClass('tree')) {
+ if(isRoot === undefined) isRoot = $list.hasClass('tree');
+ if(!isRoot) {
$parentItem = ($parentItem || $list.closest('li')).addClass('has-list');
- if(!$parentItem.find('.list-toggle').length) {
- $parentItem.prepend(this.options.toggleTemplate);
+ if(skipCheckExists || !$parentItem.find('.list-toggle').length) {
+ $parentItem.prepend(that.options.toggleTemplate);
}
- idx = idx || $parentItem.data('idx');
- } else {
- idx = 0;
- $parentItem = null;
}
- $list.removeClass('has-active-item');
- var $children = $list.attr('data-idx', idx || 0).children('li:not(.tree-action-item)').each(function(index) {
- that._initItem($(this), index + 1, $list);
- });
- if($children.length === 1 && !$children.find('ul').length)
- {
- $children.addClass('tree-single-item');
+ data = data || ($parentItem ? $parentItem.data() : {id: 0});
+ if(!skipCheckExists) {
+ $list.removeClass('has-active-item');
+ var $children = $list.attr('data-id', data.id).children('li:not(.tree-action-item)').each(function(index) {
+ var $item = $(this);
+ var item = $item.data();
+ if (item.id === undefined) item.id = data.id + '_' + index;
+ that._initItem($item, $list, item);
+ });
+ if($children.length === 1 && !$children.find('ul').length)
+ {
+ $children.addClass('tree-single-item');
+ }
}
- data = data || ($parentItem ? $parentItem.data() : null);
- var actions = formatActions(data ? data.actions : null, this.actions);
+ var actions = formatActions(data ? data.actions : null, that.actions);
if(actions) {
if(actions.add && actions.add.templateInList !== false) {
var $actionItem = $list.children('li.tree-action-item');
@@ -198,43 +214,37 @@
}, actions.sort.options, $.isPlainObject(this.options.sortable) ? this.options.sortable : null));
}
}
- if($parentItem && ($parentItem.hasClass('open') || (data && data.open))) {
+ if(!skipCheckExists && $parentItem && ($parentItem.hasClass('open') || (data && data.open))) {
$parentItem.addClass('open in');
}
};
- Tree.prototype._initItem = function($item, idx, $parentList, data) {
- if(idx === undefined) {
- var $pre = $item.prev('li');
- idx = $pre.length ? ($pre.data('idx') + 1) : 1;
- }
- $parentList = $parentList || $item.closest('ul');
- $item.attr('data-idx', idx).removeClass('tree-single-item');
- if(!$item.data('id')) {
- var id = idx;
- if(!$parentList.hasClass('tree')) {
- id = $parentList.parent('li').data('id') + '-' + id;
+ Tree.prototype._initItem = function($item, $parentUl, data, $childrenUl, skipCheckExists) {
+ var that = this;
+ data = data || $item.data();
+ if (!skipCheckExists) {
+ $parentUl = $parentUl || $item.closest('ul');
+ $item.attr('data-id', data.id).removeClass('tree-single-item');
+ if ($item.hasClass('active')) {
+ $parentUl.parent('li').addClass('has-active-item');
}
- $item.attr('data-id', id);
}
- if ($item.hasClass('active')) {
- $parentList.parent('li').addClass('has-active-item');
- }
- data = data || $item.data();
- var actions = formatActions(data.actions, this.actions);
+ var actions = formatActions(data.actions, that.actions);
if(actions) {
var $actions = $item.find('.tree-actions');
if(!$actions.length) {
- $actions = $('').appendTo(this.options.itemWrapper ? $item.find('.tree-item-wrapper') : $item);
+ $actions = $('').appendTo(that.options.itemWrapper ? $item.find('.tree-item-wrapper') : $item);
$.each(actions, function(actionName, action) {
if(action) $actions.append(createActionEle(action, actionName));
});
}
}
- var $children = $item.children('ul');
- if($children.length) {
- this._initList($children, $item, idx, data);
+ if(!skipCheckExists) {
+ $childrenUl = $childrenUl || $item.children('ul');
+ if($childrenUl.length) {
+ that._initList($childrenUl, $item, data, false, skipCheckExists);
+ }
}
};
@@ -245,10 +255,10 @@
this.$.addClass('tree');
if(options.animate) this.$.addClass('tree-animate');
- this._initList(this.$);
+ this._initList(this.$, null, null, true);
var initialState = options.initialState;
- var isPreserveEnable = $.zui && $.zui.store && $.zui.store.enable;
+ var isPreserveEnable = options.preserve !== false && $.zui && $.zui.store && $.zui.store.enable;
if(isPreserveEnable) {
this.selector = name + '::' + (options.name || '') + '#' + (this.$.attr('id') || globalId++);
this.store = $.zui.store[options.name ? 'get' : 'pageGet'](this.selector, {});