123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- /*
- * Created by MaiXinRong on 2017/2/9.
- * 项目管理 专用树结构
- */
- (function($) {
- var _setting = {
- tree: {
- id: 'ID',
- pid: 'ParentID',
- nid: 'NextSiblingID',
- btnColumn: 1,
- nullId: -1
- },
- columns: [
- {
- head: '工程列表',
- data: 'name',
- static: false,
- width: '100%',
- event: {
- getText: null,
- getIcon: null
- }
- }
- ],
- dataTemp: {
- id: -1,
- parentId: -1,
- nextId: -1,
- isTemp: true
- },
- viewEvent: {
- beforeSelect: null,
- onSelectNode: null
- }
- };
- var Node = (function () {
- function Node(tree, data) {
- this.parent = null;
- this.nextSibling = null;
- this.children = [];
- this.tree = tree;
- this.data = data;
- this.setting = tree.setting;
- this.expanded = true;
- this.row = null;
- this.expandBtn = null;
- }
- Node.prototype.firstChild = function() {
- return (this.children.length === 0) ? null : this.children[0];
- };
- Node.prototype.lastChild = function () {
- return (this.children.length === 0) ? null : this.children[this.children.length - 1];
- }
- Node.prototype.deepestRow = function () {
- return (this.children.length === 0) ? this.row : this.lastChild().deepestRow();
- }
- Node.prototype.addChild = function (child, childNext) {
- if (childNext){
- this.children.push(child);
- } else {
- if (this.childIndex(childNext) > -1){
- this.children.splice(this.childIndex(childNext) - 1, 0, child);
- } else {
- this.children.push(child);
- }
- }
- return child;
- };
- Node.prototype.childIndex = function (child) {
- return this.children.indexOf(child);
- };
- Node.prototype.depth = function () {
- return this.parent ? this.parent.depth() + 1 : 0;
- };
- Node.prototype.domId = function () {
- return this.data ? this.tree.domId + '_' + this.data[this.setting.tree.id] : '';
- };
- Node.prototype.expand = function (bool) {
- this.expanded = bool;
- _view._refreshTreeBtn(this);
- if (this.expanded) {
- _view._showNodes(this.children);
- } else {
- _view._hideNodes(this.children);
- }
- };
- Node.prototype.preSibling = function () {
- var iIndex = this.parent.childIndex(this);
- if (iIndex === -1){
- return null;
- } else {
- return iIndex > 0 ? this.parent.children[iIndex-1] : null;
- }
- };
- Node.prototype.setParent = function (parent) {
- if (parent && this.parent !== parent) {
- this.parent = parent;
- this.data[this.setting.tree.pid] = this.pid();
- }
- };
- Node.prototype.setNextSibling = function (nextSibling) {
- if (this.nextSibling !== nextSibling) {
- this.nextSibling = nextSibling;
- this.data[this.setting.tree.nid] = this.nid();
- }
- }
- Node.prototype.id = function () {
- return this.data ? this.data[this.setting.tree.id] : -1;
- };
- Node.prototype.pid = function () {
- return this.parent ? this.parent.id() : -1;
- };
- Node.prototype.nid = function () {
- return this.nextSibling ? this.nextSibling.id() : -1;
- };
- Node.prototype.propertyJoin = function (dataName) {
- return this.parent ? this.parent.propertyJoin(dataName) + ';' + this.data[dataName] : this.data[dataName];
- }
- return Node;
- })();
- var Tree = (function () {
- function Tree(obj, setting) {
- this._root = new Node(this);
- this.treeObj = obj;
- this.domId = obj.attr('id');
- this.treeHeadObj = _view._makeTableHead(this.treeObj, setting);
- this.treeBodyObj = _view._makeTableBody(this.treeObj);
- this.setting = setting;
- var _maxNodeId = 0;
- this.newNodeId = function (id) {
- if (arguments.length > 0){
- _maxNodeId = (id > _maxNodeId) ? id : _maxNodeId;
- } else {
- _maxNodeId += 1;
- return _maxNodeId;
- }
- };
- this.maxNodeId = function (id){
- if (arguments.length > 0) {
- _maxNodeId = Math.max(id, _maxNodeId);
- } else {
- return _maxNodeId;
- }
- }
- };
- Tree.prototype.firstNode = function (){
- return this._root.firstChild();
- };
- Tree.prototype.traverseDF = function(callback){
- var recurse = function (node) {
- var i;
- if (node !== this._root) {
- callback(node);
- }
- for (i = 0; i < node.children.length; i++){
- recurse(node.children[i]);
- }
- }
- recurse(this._root);
- };
- Tree.prototype.findNode = function (id){
- var treenode = null,
- callback = function (node) {
- if (node.data && node.data[node.setting.tree.id] === id){
- treenode = node;
- }
- };
- this.traverseDF.call(this, callback);
- return treenode;
- };
- Tree.prototype.findNodeByDomId = function (domId) {
- var treenode = null,
- callback = function (node) {
- if (node.domId === domId) {
- treenode = node;
- }
- };
- this.traverseDF.call(this, callback);
- return treenode;
- };
- Tree.prototype.removeNode = function (node) {
- var iIndex;
- if (node) {
- iIndex = node.parent.childIndex(node);
- if (iIndex > 0) {
- node.parent.children[iIndex - 1].setNextSibling(node.nextSibling);
- }
- node.parent.children.splice(iIndex, 1);
- }
- _view._removeNodesRowDom([node]);
- };
- Tree.prototype.loadData = function (arrData) {
- var i, that = this;
- var createTempNode = function (id, setting) {
- var tempData = {};
- tempData[setting.tree.id] = id;
- return new Node(that, tempData);
- };
- var loadNode = function (data, setting) {
- var node = that.findNode(data[setting.tree.id]) || null,
- parent = that.findNode(data[setting.tree.pid]) || null,
- next = that.findNode(data[setting.tree.nid]) || null,
- tempData;
- if (!node) {
- node = new Node(that, data);
- }
- node.data = data;
- that.maxNodeId(node.id());
- if (!parent){
- if (data[setting.tree.pid] === setting.tree.nullId) {
- parent = that._root;
- } else {
- parent = createTempNode(data[setting.tree.pid], setting);
- parent.parent = that._root;
- that._root.children.push(parent);
- }
- }
- if (node.parent && node.parent !== parent) {
- node.parent.children.splice(node.parent.childIndex(node), 1);
- }
- node.parent = parent;
- if (!next && data[setting.tree.nid] !== setting.tree.nullId) {
- next = createTempNode(data[setting.tree.nid], setting);
- next.parent = parent;
- parent.children.push(next);
- }
- node.nextSibling = next;
- if (parent.childIndex(node) === -1){
- if (!next){
- parent.children.push(node);
- } else if (parent.childIndex(next) === -1){
- parent.children.push(node);
- parent.children.push(next);
- } else {
- parent.children.splice(parent.childIndex(next), 0, node);
- }
- } else if (parent.childIndex(node) !== parent.childIndex(node.next) - 1) {
- parent.children.splice(parent.childIndex(node), 1);
- parent.children.splice(parent.childIndex(next), 0, node);
- };
- };
- for (i = 0; i < arrData.length; i++){
- loadNode(arrData[i], this.setting);
- }
- };
- Tree.prototype.refreshNodesDom = function (nodes, recurse){
- var that = this;
- nodes.forEach(function (node) {
- if (node.row) {
- $('td', node.row).remove();
- _view._makeTableRowCells(node.row, node);
- } else if (node !== that._root) {
- _view._makeRowDom(that.treeBodyObj, node);
- }
- if (recurse) {
- that.refreshNodesDom(node.children, recurse);
- }
- })
- };
- Tree.prototype.refreshTreeDom = function () {
- this.refreshNodesDom(this._root.children, true);
- };
- Tree.prototype.addNodeData = function (data, parent, nextSibling) {
- var node = null;
- var pNode = parent ? parent : this._root;
- if (!nextSibling || (nextSibling.parent === pNode && pNode.childIndex(nextSibling) > -1)) {
- node = new Node(this, data);
- this.maxNodeId(data[this.setting.tree.id]);
- node.row = _view._makeRowDom(this.treeBodyObj, node);
- this.move(node, pNode, nextSibling);
- }
- return node;
- }
- Tree.prototype.move = function(node, parent, nextSibling) {
- var iIndex = -1, pre;
- if (parent && (!nextSibling || (nextSibling.parent === parent && parent.childIndex(nextSibling) > -1))) {
- if (node) {
- if (node.parent) {
- iIndex = node.parent.childIndex(node);
- if (iIndex > 0) {
- node.parent.children[iIndex - 1].setNextSibling(node.nextSibling);
- }
- node.parent.children.splice(iIndex, 1);
- this.refreshNodesDom([node.parent], false);
- }
- if (nextSibling) {
- iIndex = parent.childIndex(nextSibling);
- if (iIndex > 0){
- pre = parent.children[iIndex - 1];
- pre.setNextSibling(node);
- parent.children.splice(iIndex - 1, 0, node);
- } else {
- parent.children.splice(0, 0, node);
- }
- } else {
- if (parent.children.length > 0){
- pre = parent.lastChild();
- pre.setNextSibling(node);
- }
- parent.children.push(node);
- }
- node.setParent(parent);
- node.setNextSibling(nextSibling);
- if (node.row) {
- if (pre) {
- _view._moveRowDom(node, pre.deepestRow());
- } else if (parent.id() !== this.setting.tree.nullId) {
- _view._moveRowDom(node, parent.row);
- } else if (nextSibling) {
- _view._moveRowDomBefore(node, nextSibling.row);
- }
- }
- if (node.parent.row) {
- this.refreshNodesDom([node.parent], false);
- }
- }
- } else {
- this.e.throw('Error: information of moving node has mistake.');
- }
- };
- Tree.prototype.selected = (function () {
- var selectNode = null;
- var select = function (node) {
- if (arguments.length === 0) {
- return selectNode;
- } else {
- if (node) {
- if (selectNode && selectNode.row) {
- selectNode.row.removeClass('table-active');
- }
- selectNode = node;
- node.row.addClass('table-active');
- }
- }
- }
- return select;
- })();
- return Tree;
- })();
- _data = {
- clone: function (obj) {
- if (obj === null) return null;
- var o = _data.isArray(obj) ? [] : {};
- for (var i in obj) {
- o[i] = (obj[i] instanceof Date) ? new Date(obj[i].getTime()) : (typeof obj[i] === "object" ? _data.clone(obj[i]) : obj[i]);
- }
- return o;
- },
- isArray: function (arr) {
- return Object.prototype.toString.apply(arr) === "[object Array]";
- }
- },
- _event = {
- _selectProj: function (node) {
- if (node.setting.viewEvent.beforeSelect) {
- node.setting.viewEvent.beforeSelect(node.tree.selected());
- }
- node.tree.selected(node);
- if (node.setting.viewEvent.onSelectNode) {
- node.setting.viewEvent.onSelectNode(node);
- }
- }
- }
- _view = {
- _makeTableHeadCell: function (obj, col){
- var th;
- th = $('<th>');
- th.attr('width', col.width);
- th.text(col.head);
- obj.append(th);
- },
- _makeTableHead: function (obj, setting){
- var thead, tr, i;
- thead = $('<thead>');
- tr = $('<tr>');
- for (i = 0; i < setting.columns.length; i++){
- _view._makeTableHeadCell(tr, setting.columns[i]);
- }
- thead.append(tr);
- obj.append(thead);
- return thead;
- },
- _makeTableBody: function (obj){
- var tbody;
- tbody = $('<tbody>');
- obj.append(tbody);
- return tbody;
- },
- _makeTableRowCell: function (obj, node, columns, index) {
- var html = [], td, i, url;
- html.push('<td ');
- if (index === node.setting.tree.btnColumn){
- html.push('class=', 'in-', node.depth().toString(), '>');
- if (node.children.length !== 0) {
- html.push('<a href="#" class="tree-open" title="收起"><i class="fa fa-minus-square-o mr-1"></i></a>');
- } else {
- html.push('<a href="#" class="tree-open" title="收起"><i></i></a>');
- }
- } else {
- html.push('>');
- }
- if (columns.event.getIcon) {
- columns.event.getIcon(html, node);
- }
- if (columns.name !== '') {
- if (columns.event.getText) {
- columns.event.getText(html, node, node.data[columns.data]);
- } else {
- html.push(node.data[columns.name]);
- }
- }
- html.push('</td>');
- td = $(html.join(''));
- if (index === node.setting.tree.btnColumn) {
- node.expandBtn = $('.tree-open>.fa', td);
- node.expandBtn.bind('click', {node: node}, function(e){
- e.data.node.expand(!e.data.node.expanded);
- });
- node.icon = $('.tree-icon', td);
- }
- if (columns.event.tdBindEvent) {
- columns.event.tdBindEvent(td, node);
- }
- obj.append(td);
- return td;
- },
- _makeTableRowCells: function (obj, node) {
- for (i = 0; i < node.setting.columns.length; i++){
- _view._makeTableRowCell(obj, node, node.setting.columns[i], i);
- }
- },
- _makeRowDom: function (obj, node) {
- var tr, i;
- tr = $('<tr>');
- obj.append(tr);
- tr.attr('id', node.domId());
- node.row = tr;
- _view._makeTableRowCells(tr, node);
- tr.click(function(){
- _event._selectProj(node);
- });
- /*$(tr).draggable({
- helper: "clone",
- opacity: .75,
- refreshPositions: true, // Performance?
- revert: "invalid",
- revertDuration: 300,
- scroll: true
- });
- tr.droppable({
- drop: function (e, ui) {
- var target = node.tree.findNodeByDomId($(this).attr('id')),
- drag = node.tree.findNodeByDomId($(ui).attr('id'));
- tree.move(drag, target);
- }
- }); */
- return tr;
- },
- _moveRowDomBefore: function (node, destination) {
- var moveNodesRowDomBefore = function (nodes) {
- nodes.forEach(function (node) {
- node.row.insertBefore(destination);
- moveNodesRowDomBefore(node.children);
- });
- }
- moveNodesRowDomBefore([node]);
- _view._refreshNodesLevelCss([node]);
- },
- _moveRowDom: function (node, destination) {
- var pre = destination,
- moveNodeRowDom = function (node) {
- node.row.insertAfter(pre);
- pre = node.row;
- moveChildrenRowDom(node);
- },
- moveChildrenRowDom = function(node){
- var i;
- for (i = 0; i < node.children.length; i++){
- moveNodeRowDom(node.children[i]);
- }
- };
- moveNodeRowDom(node);
- _view._refreshNodesLevelCss([node]);
- },
- _refreshTreeBtn: function (node) {
- var i;
- if (node.children.length === 0) {
- node.expandBtn.hide();
- } else {
- node.expandBtn.show();
- if (node.expanded) {
- node.expandBtn.removeClass('fa-plus-square-o');
- node.expandBtn.addClass('fa-minus-square-o');
- } else {
- node.expandBtn.removeClass('fa-minus-square-o');
- node.expandBtn.addClass('fa-plus-square-o');
- }
- }
- },
- _refreshNodesLevelCss: function (nodes) {
- nodes.forEach(function(node){
- var td = $('td:eq(' + node.setting.tree.btnColumn.toString() + ')', node.row);
- td.attr('class', 'in-'+ node.depth().toString());
- _view._refreshNodesLevelCss(node.children);
- })
- },
- _hideNodes: function (nodes) {
- var i, node;
- for (i = 0; i < nodes.length; i++){
- node = nodes[i];
- node.row.hide();
- _view._hideNodes(node.children);
- }
- },
- _showNodes: function (nodes) {
- var i, node;
- for (i = 0; i < nodes.length; i++){
- node = nodes[i];
- node.row.show();
- if (node.expanded) {
- _view._showNodes(node.children);
- }
- }
- },
- _removeNodesRowDom: function (nodes) {
- var i, node;
- for (i = 0; i < nodes.length; i++){
- node = nodes[i];
- _view._removeNodesRowDom(node.children);
- if (node.row) {
- node.row.remove();
- }
- }
- }
- };
- $.fn.treeTable = {
- init: function(obj, setting, arrData){
- var _treeSetting, _tree;
- _treeSetting = _data.clone(_setting);
- $.extend(true, _treeSetting, setting);
- var _tree = new Tree(obj, _treeSetting);
- _tree.loadData(arrData);
- _tree.refreshTreeDom();
- return _tree;
- }
- }
- })(jQuery);
|