/* Product Name: dhtmlxSuite Version: 5.2.0 Edition: Professional License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com Copyright UAB Dinamenta http://www.dhtmlx.com */ function dhtmlXTreeView(conf) { // console.log("add cache for kids for removeItem"); // console.log("add unload"); var that = this; if (typeof(conf) == "object" && conf.tagName == null) { // api-init } else { conf = {parent: conf, clear: true}; } this.base = (typeof(conf.parent)=="string"?document.getElementById(conf.parent):conf.parent); if (this.base != document.body) { while (this.base.childNodes.length > 0) this.base.removeChild(this.base.lastChild); } this.conf = { skin: (conf.skin||window.dhx4.skin||(typeof(dhtmlx)!="undefined"?dhtmlx.skin:null)||window.dhx4.skinDetect("dhxtreeview")||"material"), tree_id: window.dhx4.newId(), // register tree in common pull ofs: {w: 1, h: 0}, // skyblue only adjust_base: false, icons: this.icons[(typeof(conf.iconset) == "string" && this.icons[conf.iconset] != null && this.icons[conf.iconset].r == true ? conf.iconset : "tree_native")], autoload: { url: null, // will set automaticaly from 1st loadStruct mode: "id" // user function allowed here }, selected: {}, ud: {}, // usersdata idx: {sign:0,icon:1,text:2}, // icons index silent: false, // do not callEvent if true // macos related for selection is_mac: (navigator.platform.match(/^mac/i) != null && typeof(window.addEventListener) == "function"), mac_cmd_key: false }; this.setSkin(this.conf.skin); this.cont = document.createElement("DIV"); this.cont.className = "dhxtreeview_cont"; this.base.appendChild(this.cont); this.area = document.createElement("DIV"); this.area.className = "dhxtreeview_area"; this.cont.appendChild(this.area); this.cont.onclick = function(e) { e = e||event; that.callEvent("_onTreeClick", [e, {stop:false}]); } this.cont.ondblclick = function(e) { e = e||event; var t = (e.target||e.srcElement); if (t.className.match(/dhxtreeview_item_label/) != null) { that._openCloseItem(t.parentNode.parentNode._itemId, true); } } this.items = {}; this._addItem = function(id, pId, data, index) { var level = (pId!=null?this.items[pId].level+1:1); var t = document.createElement("DIV"); t.className = "dhxtreeview_item"; t.innerHTML = "
"; if (index != null && index < 0) data.index = 0; if (pId == null) { var node = this.area; } else { var k = this.items[pId].kids; if (k == false) this._initKidsNode(pId); this.items[pId].kids_request = false; // do not use dyn load if at least 1 child is present var node = this.items[pId].item.lastChild.firstChild; } if (index != null && node.childNodes[index] != null) { node.insertBefore(t, node.childNodes[index]); } else { node.appendChild(t); } node = null; t._itemId = id; t._treeId = this.conf.tree_id; if (window.dhx4.isIE == true) { t.onselectstart = function(e){ e = e||event; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; } } this.items[id] = { id: id, pId: pId, treeId: this.conf.tree_id, text: data.text, item: t, level: level, kids: false, // true/false if any kid opened: window.dhx4.s2b(data.open), userdata: window.dhx4._copyObj(data.userdata||{}), half_opened: false // true/false to change sign only, used for dyn.load }; this.callEvent("_onItemRendered", [id, data]); t.firstChild.innerHTML = this._getItemHtml(id); t = null; // pre-select if (window.dhx4.s2b(data.select) == true) this._setSelected(id, true); this.callEvent("_onItemInited", [id, data]); } this.addItem = function(id, text, parentId, index) { if (this.items[id] != null) return; if (parentId != null && this.items[parentId] == null) parentId = null; this._addItem(id, parentId, {text: text}, index); this._callPublicEvent("onAddItem", [id, text, parentId, index]); } this._removeSingleItem = function(id) { if (window.dhx4.isIE == true) this.items[id].item.onselectstart = null; this.items[id].item.parentNode.removeChild(this.items[id].item); for (var a in this.items[id]) { this.items[id][a] = null; delete this.items[id][a]; } delete this.items[id]; // clear selection if any if (this.conf.selected[id] == true) delete this.conf.selected[id]; } this._removeItem = function(id) { var pid = id ? this.items[id].pId : -1; var count = -1; // remove nested for (var a in this.items) { if (this.items[a].pId == pid) count++; if (this.items[a].pId == id) this._removeItem(a); } if (id != null) this._removeSingleItem(id); if (pid && !count) this._clearKidsNode(pid); } this.deleteItem = function(id) { if (this.items[id] == null) return; if (!this._callPublicEvent("onBeforeDeleteItem", [id])) return; this._removeItem(id); this._callPublicEvent("onDeleteItem", [id]); } this.deleteChildItems = function(id) { id = id || 0; for (var a in this.items) { if (this.items[a].pId == id) this._removeItem(a); } this._clearKidsNode(id); } this.clearAll = function() { this._removeItem(null); if (this.conf.unloading != true) this._fixAreaWidth(); } this._initKidsNode = function(id) { var p; if (this.items[id].item.lastChild.className.match(/dhxtreeview_kids_cont/) == null) { p = document.createElement("DIV"); p.className = "dhxtreeview_kids_cont"; p.innerHTML = "
"; p.style.opacity = "1"; if (this.items[id].opened != true) { if (this.conf.transProp != false) { p.style.height = "0px"; p.style.opacity = "0"; p.firstChild.style.display = "none"; } else { p.style.display = "none"; } } this.items[id].item.appendChild(p); } this.items[id].kids = true; this._iconUpdate(id); this._signUpdate(id); p = null; } this._clearKidsNode = function(id) { if (this.items[id].item.lastChild.className.match(/dhxtreeview_kids_cont/) != null) { this.items[id].item.removeChild(this.items[id].item.lastChild); } this.items[id].kids = false; this._iconUpdate(id); this._signUpdate(id); } // open/colse this.openItem = function(id, anim) { if (this.items[id].opened != true) { if (typeof(anim) == "undefined") anim = true; this._openCloseItem(id, anim); } } this.closeItem = function(id, anim) { if (this.items[id].opened == true) { if (typeof(anim) == "undefined") anim = true; this._openCloseItem(id, anim); } } this._openCloseItem = function(id, anim) { if (this.callEvent("_onBeforeOpen", [id]) !== true) return; if (!(this.items[id].kids == true || this.items[id].kids_request == true)) return false; if (this.items[id].half_opened == true) { this.items[id].half_opened = false; this._signUpdate(id); return; } if (anim && this.conf.transProp != false) { if (!this.items[id].transEv) { this.items[id].item.lastChild.addEventListener(this.conf.transEv, this._doOnTrEnd); this.items[id].transEv = true; } if (this.items[id].opened == true) { // close this.items[id].transMode = "close"; this.items[id].item.lastChild.style.overflow = "hidden"; this.items[id].item.lastChild.style.height = this.items[id].item.lastChild.childNodes[0].offsetHeight+"px"; window.setTimeout(function(){ that.items[id].item.lastChild.style[that.conf.transProp] = that.conf.transValueHeight; that.items[id].item.lastChild.style.height = "0px"; that.items[id].item.lastChild.style.opacity = "0"; that.items[id].opened = false; that._iconUpdate(id); that._signUpdate(id); },50); } else { // open this.items[id].transMode = "open"; this.items[id].item.lastChild.style[this.conf.transProp] = this.conf.transValueHeight; this.items[id].item.lastChild.childNodes[0].style.display = ""; this.items[id].item.lastChild.style.overflow = "hidden"; this.items[id].item.lastChild.style.height = this.items[id].item.lastChild.childNodes[0].offsetHeight+"px"; this.items[id].item.lastChild.style.opacity = "1"; this.items[id].opened = true; this._iconUpdate(id); this._signUpdate(id); } } else { // open/close this.items[id].opened = !this.items[id].opened; this.items[id].item.lastChild.style.display = (this.items[id].opened==true ? "" : "none"); // add for dnd this.items[id].item.lastChild.childNodes[0].style.display = this.items[id].item.lastChild.style.display; this.items[id].item.lastChild.style.height = (this.items[id].opened==true?"":"0px"); this.items[id].item.lastChild.style.opacity = (this.items[id].opened==true?1:0); // end for dnd this._iconUpdate(id); this._signUpdate(id); this._fixAreaWidth(); } } this._doOnTrEnd = function() { var id = this.parentNode._itemId; that.items[id].item.lastChild.style[that.conf.transProp] = ""; if (that.items[id].transMode == "close") { that.items[id].item.lastChild.childNodes[0].style.display = "none"; //that._iconUpdate(id); } else { that.items[id].item.lastChild.style.height = ""; that.items[id].item.lastChild.style.overflow = ""; } that._fixAreaWidth(); } // dimension this.setSizes = function() { // adjust top-parent, used in window when tree has border if (this.conf.adjust_base == true) { this.base.style.width = this.base.parentNode.clientWidth-2+"px"; this.base.style.height = this.base.parentNode.clientHeight-2+"px"; } // this.cont.style.left = this.conf.ofs.w+"px"; this.cont.style.top = this.conf.ofs.h+"px"; this.cont.style.width = this.base.clientWidth-this.conf.ofs.w*2+"px"; this.cont.style.height = this.base.clientHeight-this.conf.ofs.h*2+"px"; // this._fixAreaWidth(); } this._fixAreaWidth = function(r) { this.area.style.width = "100%"; if (this.cont.scrollWidth != this.cont.clientWidth) { this.area.style.width = this.cont.scrollWidth+1+"px"; } if (window.dhx4.isIE7 == true && r !== false) { // extra loop for ie7 to fix scroll artefacts window.setTimeout(function(){that._fixAreaWidth(false);},1); } } this.setSizes(); dhx4._eventable(this); // transition var k = window.dhx4.transDetect(); this.conf.transProp = k.transProp; this.conf.transEv = k.transEv; this.conf.transValueHeight = "height 0.15s"; k = null; // macos multiselect if (this.conf.is_mac == true) { this._macOnKey = function(e) { if (((window.dhx4.isKHTML || window.dhx4.isChrome || window.dhx4.isOpera) && (e.keyCode == 91 || e.keyCode == 93)) || (window.dhx4.isFF && e.keyCode == 224)) { that.conf.mac_cmd_key = (e.type == "keydown"); } } window.addEventListener("keydown", this._macOnKey, false); window.addEventListener("keyup", this._macOnKey, false); } // extra modules to init if any for (var a in this.modules) { if (this.modules[a].init != null) this[this.modules[a].init](conf); } this.unload = function() { this.conf.unloading = true; this.cont.onclick = null; this.cont.ondblclick = null; this.clearAll(); if (this.conf.is_mac == true) { window.removeEventListener("keydown", this._macOnKey, false); window.removeEventListener("keyup", this._macOnKey, false); } // extra modules to unload if any for (var a in this.modules) { if (this.modules[a].unload != null) this[this.modules[a].unload](); } this.area.parentNode.removeChild(this.area); this.area = null; this.cont.parentNode.removeChild(this.cont); this.cont = null; this.base.className = String(this.base.className).replace(new RegExp("\s{0,}dhxtreeview_"+(this.conf.skin||"")), ""); window.dhx4._eventable(this, "clear"); for (var a in this) this[a] = null; that = null; } // autoload/etc if (conf.items != null || conf.json != null || conf.xml != null) { this.loadStruct(conf.items||conf.json||conf.xml, conf.onload); } return this; }; dhtmlXTreeView.prototype.modules = {}; // misc dhtmlXTreeView.prototype.setSkin = function(skin) { this.base.className = String(this.base.className).replace(new RegExp("\s{0,}dhxtreeview_"+(this.conf.skin||"")), "") + " dhxtreeview_"+skin; this.conf.skin = skin; this.conf.icon_width = dhx4.readFromCss("dhxtreeview_"+this.conf.skin+" dhxtreeview_icon_width"); this.conf.ofs = (this.conf.skin == "dhx_skyblue" ? {w:1, h:0} : {w:0, h:0}); }; dhtmlXTreeView.prototype.setItemText = function(id, text) { if (this.items[id] != null) { this.items[id].text = text; this.items[id].item.firstChild.childNodes[this.conf.idx.text].innerHTML = text; this._callPublicEvent("onTextChange", [id, text]); } }; dhtmlXTreeView.prototype.getItemText = function(id) { return this.items[id].text; }; dhtmlXTreeView.prototype.showItem = function(id) { var top = 0; var sub = false; while (id){ var node = this.items[id]; if (node){ top += node.item.offsetTop + (sub?node.item.firstChild.offsetHeight:0); id = node.pId; sub = true; } else break; } this.cont.scrollTop = top; }; // dhtmlXTreeView.prototype.getParentId = function(id) { return this.items[id].pId; }; dhtmlXTreeView.prototype.getSubItems = function(parentId) { var rt = this.items[parentId]; rt = rt ? rt.item.lastChild.firstChild : this.area; var t = []; for (var i = 0; i < rt.childNodes.length; i++) t[i] = rt.childNodes[i]._itemId; return t; }; // render item html dhtmlXTreeView.prototype._refreshItemHtml = function(id, updSign, updIcon) { this.items[id].item.firstChild.innerHTML = this._getItemHtml(id); if (updSign == true) this._signUpdate(id); if (updIcon == true) this._iconUpdate(id); }; dhtmlXTreeView.prototype._getItemHtml = function(id) { var html = []; var nodeIndex = 0; for (var a in this.conf.idx) { var data = this["_itemHtml_"+a](id, nodeIndex); if (data.nodeText !== false) { html.push(data.nodeText); nodeIndex += data.nodeIndex; } } return html.join(""); }; dhtmlXTreeView.prototype._getIconOfs = function(id, index) { return ((this.items[id].level-1+index)*this.conf.icon_width); }; dhtmlXTreeView.prototype._itemHtml_text = function(id, nodeIndex) { return { nodeIndex: 1, nodeText: "
"+this.items[id].text+"
" }; }; // userdata dhtmlXTreeView.prototype.setUserData = function(id, name, value) { var item = this.items[id]; if (item) item.userdata[name] = value; }; dhtmlXTreeView.prototype.getUserData = function(id, name) { var item = this.items[id]; if (item && !name) return item.userdata; return item ? (item.userdata[name]||null) : null; }; // events extension dhtmlXTreeView.prototype.silent = function(f) { this.conf.silent = true; if (typeof(f) == "function") f.apply(window, [this]); this.conf.silent = false; }; dhtmlXTreeView.prototype._callPublicEvent = function() { return (this.conf.silent == false ? this.callEvent.apply(this, arguments) : true); }; dhtmlXTreeView.prototype.refreshItem = function(id){ id = id || 0; this.deleteChildItems(id); this._dynLoadRequest(id); } dhtmlXTreeView.prototype.getLevel = function(id){ var top = this.items[id]; var level = 0; while (top){ level++; top = this.items[top.pId]; } return level; } if (typeof(window.dhtmlXCellObject) == "function") { dhtmlXCellObject.prototype.attachTreeView = function(conf) { this.callEvent("_onBeforeContentAttach", ["treeview"]); var obj = document.createElement("DIV"); obj.style.position = "relative"; obj.style.overflow = "hidden"; obj.style.width = "100%"; obj.style.height = "100%"; this._attachObject(obj); var treeConf = {parent: obj, skin: this.conf.skin}; if (conf != null && typeof(conf) == "object") { for (var a in conf) { if (typeof(treeConf[a]) == "undefined") treeConf[a] = conf[a]; } } this.dataType = "treeview"; this.dataObj = new dhtmlXTreeView(treeConf); // draw border if attached to window if (typeof(window.dhtmlXWindowsCell) == "function" && this instanceof window.dhtmlXWindowsCell) { obj.className += " dhxtreeview_with_border"; this.dataObj.conf.adjust_base = true; this.dataObj.setSizes(); } treeConf.parent = null; treeConf = obj = conf = null; this.callEvent("_onContentAttach", []); return this.dataObj; }; } // register checkboxes module dhtmlXTreeView.prototype.modules.chbx = { init: "_chbxInit" }; // public dhtmlXTreeView.prototype.enableCheckboxes = function(mode) { mode = (mode==true); if (this.conf.enable_chbx != mode) { this.conf.enable_chbx = mode; this._chbxUpdIndex(); for (var a in this.items) this._refreshItemHtml(a, true, true); } }; dhtmlXTreeView.prototype.getAllChecked = function(parentId) { return this._chbxGetCheckedBranch(parentId, true); }; dhtmlXTreeView.prototype.getAllUnchecked = function(parentId) { return this._chbxGetCheckedBranch(parentId, false); }; dhtmlXTreeView.prototype.checkItem = function(id) { this._chbxSetChecked(id, true, true); }; dhtmlXTreeView.prototype.uncheckItem = function(id) { this._chbxSetChecked(id, false, true); }; dhtmlXTreeView.prototype.isItemChecked = function(id) { if (this.items[id] == null) return null; return (this.items[id].checked == true); }; dhtmlXTreeView.prototype.enableCheckbox = function(id) { this._chbxSetEnabled(id, true); }; dhtmlXTreeView.prototype.disableCheckbox = function(id) { this._chbxSetEnabled(id, false); }; dhtmlXTreeView.prototype.isCheckboxEnabled = function(id) { return (this.items[id].chbx_enabled == true); }; dhtmlXTreeView.prototype.showCheckbox = function(id) { this._chbxSetVisible(id, true); }; dhtmlXTreeView.prototype.hideCheckbox = function(id) { this._chbxSetVisible(id, false); }; dhtmlXTreeView.prototype.isCheckboxVisible = function(id) { return (this.items[id].chbx_visible == true); }; // private dhtmlXTreeView.prototype._chbxInit = function(conf) { // init this.enableCheckboxes(conf.checkboxes); this.attachEvent("_onItemRendered", function(id, data){ this.items[id].checked = window.dhx4.s2b(data.checked); var conf = (data.checkbox||"enabled,visible"); this.items[id].chbx_enabled = (conf.match(/disabled/)==null); this.items[id].chbx_visible = (conf.match(/hidden/)==null); }); this.attachEvent("_onTreeClick", function(e, flow){ if (this.conf.enable_chbx != true) return; var t = (e.target||e.srcElement); if (t.tagName.toLowerCase() == "i") t = t.parentNode; // check if icon if ((t.parentNode.className||"").match(/dhxtreeview_item_text/) != null && t == t.parentNode.childNodes[this.conf.idx.chbx]) { // check if checkbox var id = t.parentNode.parentNode._itemId; if (this.items[id].chbx_enabled == true) this._chbxSetChecked(id, !this.items[id].checked, true); flow.stop = true; } }); conf = null; }; dhtmlXTreeView.prototype._itemHtml_chbx = function(id, nodeIndex) { var r = {nodeIndex: 0, nodeText: false}; if (this.conf.enable_chbx == true) { if (this.items[id].chbx_visible == true) r.nodeIndex = 1; r.nodeText = "
"+this._chbxGenIcon(id)+"
"; } return r; }; dhtmlXTreeView.prototype._chbxSetChecked = function(id, state) { if (this.conf.enable_chbx != true) return; state = (state==true); if (this.items[id].checked != state) { if (this._callPublicEvent("onBeforeCheck", [id, (this.items[id].checked==true)]) !== true) return; this.items[id].checked = state; this.items[id].item.childNodes[0].childNodes[this.conf.idx.chbx].innerHTML = this._chbxGenIcon(id); this._callPublicEvent("onCheck", [id, state]); } }; dhtmlXTreeView.prototype._chbxSetEnabled = function(id, mode) { if (this.items[id].chbx_enabled != mode) { this.items[id].chbx_enabled = mode; this.items[id].item.firstChild.childNodes[this.conf.idx.chbx].innerHTML = this._chbxGenIcon(id); } }; dhtmlXTreeView.prototype._chbxSetVisible = function(id, mode) { if (this.items[id].chbx_visible != mode) { this.items[id].chbx_visible = mode; this._refreshItemHtml(id, true, true); } }; dhtmlXTreeView.prototype._chbxGenIcon = function(id) { var icon = this.conf.icons["chbx_"+(this.items[id].chbx_enabled?"":"dis_")+(this.items[id].checked?"1":"0")]; return ''; }; dhtmlXTreeView.prototype._chbxUpdIndex = function() { if (this.conf.enable_chbx == true) { this.conf.idx = {sign: 0, chbx: 1, icon: 2, text: 3}; } else { this.conf.idx = {sign: 0, icon: 1, text: 2}; } }; dhtmlXTreeView.prototype._chbxGetCheckedBranch = function(pId, mode) { var k = []; for (var a in this.items) { if (this.items[a].pId == pId) { if (this.items[a].checked == mode) k.push(a); if (this.items[a].kids == true) k = k.concat(this._chbxGetCheckedBranch(a, mode)); } } return k; }; // register selection module dhtmlXTreeView.prototype.modules.sign = { init: "_signInit" }; // private dhtmlXTreeView.prototype._signInit = function() { this.attachEvent("_onTreeClick", function(e, flow){ if (flow.stop == true) return; // check if cancelled by prev attached function var t = (e.target||e.srcElement); if (t.tagName.toLowerCase() == "i") t = t.parentNode; // check if icon if ((t.parentNode.className||"").match(/dhxtreeview_item_text/) != null && t == t.parentNode.childNodes[this.conf.idx.sign]) { this._openCloseItem(t.parentNode.parentNode._itemId, true); flow.stop = true; } }); }; dhtmlXTreeView.prototype._signUpdate = function(id) { var t = this.items[id]; var img = t.item.childNodes[0].childNodes[this.conf.idx.sign]; if (t.kids == true || t.kids_request == true) { img.innerHTML = ''; } else { img.innerHTML = ""; } t = img = null; } dhtmlXTreeView.prototype._itemHtml_sign = function(id, nodeIndex) { // item html renderer return { nodeIndex: 1, nodeText: "
" }; }; // register selection module dhtmlXTreeView.prototype.modules.selection = { init: "_selectionInit" }; // public dhtmlXTreeView.prototype.selectItem = function(id) { if (this.conf.msel == true) { var t = {}; if (!(id instanceof Array)) id = [id]; for (var q=0; q 300){ this._callPublicEvent("onClick", [selectId]); this._click_timer = now; this._click_item = selectId; } else { this._callPublicEvent("onDblClick", [selectId]); this._click_item = null; } if (this.conf.msel == true) { if ((e.ctrlKey == true || this.conf.mac_cmd_key == true) && e.shiftKey == false && e.altKey == false) { // ctrl pressed this._setSelected(selectId, !this._isSelected(selectId)); } else if (e.ctrlKey == false && e.shiftKey == false && e.altKey == false && this.conf.mac_cmd_key == false) { // nothing pressed if (this._clearSelection(selectId) == false) this._setSelected(selectId, true); } } else { if (this._clearSelection(selectId) == false) this._setSelected(selectId, true); } } }); }; dhtmlXTreeView.prototype._setSelected = function(id, mode) { if (mode == true) { if (this.conf.selected[id] != true) { this.items[id].item.childNodes[0].className += " dhxtreeview_item_text_selected"; this.conf.selected[id] = true; this._callPublicEvent("onSelect", [id, true]); } } else { if (this.conf.selected[id] == true) { this.items[id].item.childNodes[0].className = String(this.items[id].item.childNodes[0].className).replace(/\s*dhxtreeview_item_text_selected/gi, ""); delete this.conf.selected[id]; this._callPublicEvent("onSelect", [id, false]); } } }; dhtmlXTreeView.prototype._clearSelection = function(exceptId) { var r = false; for (var a in this.conf.selected) { if (exceptId != null && a == exceptId) r = true; else this._setSelected(a, false); } return r; // true if item stay selected }; dhtmlXTreeView.prototype._isSelected = function(id) { return (this.conf.selected[id]==true); }; // register icons module dhtmlXTreeView.prototype.modules.icons = { init: "_iconModuleInit" }; // public dhtmlXTreeView.prototype.setItemIcons = function(id, icons) { if (icons == null && this.items[id].icons != null) { delete this.items[id].icons; // clear all custom for certain item } else if (icons != null) { if (this.items[id].icons == null) this.items[id].icons = {}; for (var a in icons) { if (icons[a] != null) { this.items[id].icons[a] = icons[a]; } else if (icons[a] == null && this.items[id].icons[a] != null) { delete this.items[id].icons[a]; // clear only specified icon } } } this._iconUpdate(id); }; dhtmlXTreeView.prototype.setIconColor = function(id, color) { var icon = this.items[id].item.firstChild.childNodes[this.conf.idx.icon].firstChild; if (color == null) { if (this.items[id].icon_color != null) { delete this.items[id].icon_color; icon.style.color = "inherit"; } } else { if (this.items[id].icon_color != color) { this.items[id].icon_color = color; icon.style.color = color; } } icon = null; }; dhtmlXTreeView.prototype.setIconset = function(name) { if (this.icons[name] != null && this.icons[name].r == true) { this.conf.icons = this.icons[name]; } }; // private dhtmlXTreeView.prototype._iconModuleInit = function() { // init this.attachEvent("_onItemRendered", function(id, data){ if (data.icons != null) this.items[id].icons = data.icons; if (data.icon_color != null) this.items[id].icon_color = data.icon_color; }); }; dhtmlXTreeView.prototype._iconConf = function(id) { // return array with icons var icons = this.items[id].icons||{}; for (var a in {folder_opened:1, folder_closed:1, file:1}) { if (typeof(icons[a]) == "undefined") icons[a] = this.conf.icons[a]; // if item has own icons missing will updated here } return icons; }; dhtmlXTreeView.prototype._iconHtml = function(id, css) { // generate for icon var attrs = ['class="'+this.conf.icons.prefix+" "+css+'"']; if (this.items[id].icon_color != null) attrs.push('style="color:'+this.items[id].icon_color+';"'); return ""; }; dhtmlXTreeView.prototype._itemHtml_icon = function(id, nodeIndex) { // item html renderer return { nodeIndex: 1, nodeText: "
"+this._iconHtml(id, this._iconConf(id).file)+"
" }; }; dhtmlXTreeView.prototype._iconUpdate = function(id) { // update icon inner call var t = this.items[id]; var icons = this._iconConf(id); var css = (t.kids == true || t.kids_request == true ? icons[t.opened?"folder_opened":"folder_closed"] : icons.file); t.item.childNodes[0].childNodes[this.conf.idx.icon].innerHTML = this._iconHtml(id, css); t = null; }; // config dhtmlXTreeView.prototype.icons = { tree_native: { r: true, // allow rendering depending on browser prefix: "dhxtreeview_icon", // common prefix for all icons/arrows/checkboxes/etc plus: "dhxtreeview_icon_plus", minus: "dhxtreeview_icon_minus", file: "dhxtreeview_icon_file", folder_opened: "dhxtreeview_icon_folder_opened", folder_closed: "dhxtreeview_icon_folder_closed", loading: "dhxtreeview_icon_loading", chbx_0: "dhxtreeview_icon_chbx_0", chbx_1: "dhxtreeview_icon_chbx_1", chbx_dis_0: "dhxtreeview_icon_chbx_dis_0", chbx_dis_1: "dhxtreeview_icon_chbx_dis_1" }, font_awesome: { r: (!(window.dhx4.isIE6 == true || window.dhx4.isIE7 == true)), prefix: "fa", plus: "fa-caret-right", minus: "fa-caret-down", file: "fa-file-o", folder_opened: "fa-folder-open-o", folder_closed: "fa-folder-o", loading: "fa-refresh fa-spin", chbx_0: "fa-square-o", chbx_1: "fa-check-square-o", chbx_dis_0: "fa-square-o dhx-disabled", chbx_dis_1: "fa-check-square-o dhx-disabled" } }; // register loading module dhtmlXTreeView.prototype.modules.loading = { init: "_loadingInit", unload: "_loadingUnload" }; dhtmlXTreeView.prototype._loadingInit = function(conf) { window.dhx4._enableDataLoading(this, "_initObj", "_xmlToObj", "tree", {struct:true}); this.conf.root_id = (typeof(conf.root_id)=="undefined" || conf.root_id==null ? "0" : conf.root_id); // top-level item this._dhxdataload.onBeforeXLS = function(url) { // add tree_id for 1st load if any if (this.conf.autoload.url == null) this.conf.autoload.url = url; return {url:url.replace(/\{id\}/gi, this.conf.root_id)}; } }; dhtmlXTreeView.prototype._loadingUnload = function() { window.dhx4._enableDataLoading(this, null, null, null, "clear"); }; dhtmlXTreeView.prototype._initObj = function(data, url, pId, fixArea) { for (var q=0; q 0) { // nested items var nested = this._xmlToObj(node, true); if (nested.length > 0) item.items = nested; // icons and userdata for (var w=0; w= 2) return false; var id = null; var treeId = null; var t = e.target||e.srcElement; var ofs_x = window.dhx4.absLeft(t)+(typeof(e.offsetX)=="undefined"?e.layerX:e.offsetX) - e.clientX; var ofs_y = window.dhx4.absTop(t)+(typeof(e.offsetY)=="undefined"?e.layerY:e.offsetY) - e.clientY; while (t != null && t != that.cont) { if ((t.className||"").match(/dhxtreeview_item/) != null && t._itemId != null) { id = t._itemId; treeId = t._treeId; t = null; } else { t = t.parentNode; } } t = null; if (id == null) return; // check if empty click and abort that.conf.dnd = { inited: false, id: id, treeId: treeId, selected: (that.conf.selected[id]==true), tid: null, drop: {}, x: e.clientX, y: e.clientY, ofs_x: ofs_x, ofs_y: ofs_y, zi: window.dhx4.newId(), scroll: false, scroll_ofs: 5, // offset for single loop scroll_time: 30, // timeout scroll_tm: null, kids: {}, // all kids of dragged to prevent dnd in advance idx: {} }; that._dndInitEvents(); } this._dndOnMouseMove = function(e) { e = e||event; if (that.conf.dnd.inited != true) { if (Math.abs(that.conf.dnd.x - e.clientX) >= 15 || Math.abs(that.conf.dnd.y - e.clientY) >= 15) { if (that._callPublicEvent("onBeforeDrag", [that.conf.dnd.id]) !== true) return; that.conf.dnd.inited = true; that.cont.className += " dhxtreeview_dnd_mode"; that._dndInitDraggedObj(); that._dndCollectKids(that.conf.dnd.id); that._dndCollectIndexes(that.area); // rearrange selection if (that._clearSelection(that.conf.dnd.id) == false) that._setSelected(that.conf.dnd.id, true); // update item css that.items[that.conf.dnd.id].item.className += " dhxtreeview_item_dragged"; document.body.className += " dhxtreeview_dnd_mode"; // tree area to check if scroll should be performed that.conf.dnd.cont = { x1: window.dhx4.absLeft(that.base), y1: window.dhx4.absTop(that.base) }; that.conf.dnd.cont.x2 = that.conf.dnd.cont.x1 + that.base.offsetWidth; that.conf.dnd.cont.y2 = that.conf.dnd.cont.y1 + that.base.offsetHeight; } else { return; } } that.conf.dnd.x = e.clientX; that.conf.dnd.y = e.clientY; that._dndAdjustDraggedObj(); // check tree area edges and scroll content if any var stopScroll = true; if (that.cont.scrollHeight > that.cont.clientHeight) { if (that.conf.dnd.x >= that.conf.dnd.cont.x1 && that.conf.dnd.x <= that.conf.dnd.cont.x2) { if (that.cont.scrollTop > 0 && that.conf.dnd.y >= that.conf.dnd.cont.y1 && that.conf.dnd.y <= that.conf.dnd.cont.y1 + 10) { // top edge that._dndScroll("up"); stopScroll = false; } else if (that.cont.scrollTop+that.cont.clientHeight < that.cont.scrollHeight && that.conf.dnd.y <= that.conf.dnd.cont.y2 && that.conf.dnd.y >= that.conf.dnd.cont.y2 - 10) { // bottom edge that._dndScroll("down"); stopScroll = false; } } } if (stopScroll == true && that.conf.dnd.scroll == true) { that._dndScroll("stop"); } // detect node by target var t = (e.target||e.srcElement); // remove blink artefact if any if (t.parentNode != null && (t.parentNode.className||"").match(/dhxtreeview_kids_cont/) != null) { t = null; return; } var upd = false; var tid = null; var treeId = null; if (t.className != null) { if (t.className.match(/dhxtreeview_item_[li]/) != null) { // label/icon tid = t.parentNode.parentNode._itemId; treeId = t.parentNode.parentNode._treeId; } else if (t.className.match(/dhxtreeview_item_[t]/) != null) { // text tid = t.parentNode._itemId; treeId = t.parentNode._treeId; } } // check if the same tree if (tid != null && treeId != that.conf.dnd.treeId) { return; } // check if target is the same or if target is child if (that.conf.dnd.id == tid || that.conf.dnd.kids[tid] == true) { tid = null; } if (tid != null) { var h = that.items[tid].item.firstChild.offsetHeight; var ofs = Math.max(Math.floor(Math.min(e.offsetY, h) * 3 / h), 0); // depending on item type and offset - allow/block some offsets if (ofs == 0) { // drop as sibling above target if (that.items[tid].item.previousSibling == that.items[that.conf.dnd.id].item) { // do not allow if prev sibling is dragged ofs = null; } } else if (ofs == 1) { // drop as child of target if (that.items[that.conf.dnd.id].pId == tid) { // if already child of selected parent ofs = null; } else if (that.items[tid].kids == true && that.items[tid].item.lastChild.firstChild.firstChild == that.items[that.conf.dnd.id].item) { // do not allo if dragged already 1st child ofs = null; } else if (that.items[tid].opened == false) { // open node //that._openCloseItem(tid, true); } } else if (ofs == 2) { // drop as sibling below target if (that.items[tid].opened == true) { // do not allow for opened item ofs = null; } else if (that.items[tid].item.nextSibling == that.items[that.conf.dnd.id].item) { // do not allow if next sibling is dragged ofs = null; } } // if (ofs != that.conf.dnd.ofs) { that.conf.dnd.ofs = ofs; upd = true; } } if (tid != that.conf.dnd.tid) { // clear old one if (that.conf.dnd.tid != null) { that._dndUpdateTargetCss(that.conf.dnd.tid, false); } // update new if (tid != null) { upd = true; } that.conf.dnd.tid = tid; } if (upd == true) { var mode = false; if (ofs != null) { var drop = { id: that.conf.dnd.id, pId: that.items[tid].pId||null, index: null, idxOfs: (that.items[that.conf.dnd.id].pId == that.items[tid].pId && that.conf.dnd.idx[that.conf.dnd.id] < that.conf.dnd.idx[tid] ? -1 : 0) }; if (ofs == 0 || ofs == 2) { drop.index = that.conf.dnd.idx[tid]+(ofs==2?1:0)+drop.idxOfs; } else if (ofs == 1) { drop.pId = tid; drop.index = (that.items[tid].item.lastChild.className.match(/dhxtreeview_kids_cont/)==null?0:that.items[tid].item.lastChild.firstChild.childNodes.length); } if (that.conf.dnd.drop.id != drop.id || that.conf.dnd.drop.pId != drop.pId || that.conf.dnd.drop.index != drop.index) { that.conf.dnd.drop = drop; if (that._callPublicEvent("onDragOver", [that.conf.dnd.drop.id, that.conf.dnd.drop.pId, that.conf.dnd.drop.index]) === true) mode = true; } } if (mode != true) that.conf.dnd.ofs = ofs = null; that._dndUpdateTargetCss(tid, mode); } } this._dndOnMouseUp = function(e) { e = e||event; if (typeof(e.button) != "undefined" && e.button >= 2) return; that._dndUnloadEvents(); that._dndUnloadDraggedObj(); if (that.conf.dnd.scroll == true) { that._dndScroll("stop"); } if (that.cont.className.match(/dhxtreeview_dnd_mode/gi) != null) { that.cont.className = String(that.cont.className).replace(/\s*dhxtreeview_dnd_mode/gi, ""); } if (that.conf.dnd.tid != null) { that._dndUpdateTargetCss(that.conf.dnd.tid, false); } if (that.conf.dnd.inited == true) { that.items[that.conf.dnd.id].item.className = String(that.items[that.conf.dnd.id].item.className).replace(/\s*dhxtreeview_item_dragged/gi, ""); document.body.className = String(document.body.className).replace(/\s*dhxtreeview_dnd_mode/, ""); if (that.conf.dnd.tid != null && that.conf.dnd.ofs != null) { if (that._callPublicEvent("onBeforeDrop", [that.conf.dnd.drop.id, that.conf.dnd.drop.pId, that.conf.dnd.drop.index]) === true) { var obj = that.items[that.conf.dnd.id]; var tobj = that.items[that.conf.dnd.tid]; var pobj = (obj.pId != null ? that.items[obj.pId] : null); // prev_parent id var levelOfs; // 1) dom if (that.conf.dnd.ofs == 1) { var open = false; if (tobj.kids == false) { that._initKidsNode(tobj.id); open = true; } tobj.item.lastChild.firstChild.appendChild(obj.item); // if (open == true) { that._openCloseItem(tobj.id, false); } obj.pId = tobj.id; levelOfs = tobj.level+1-obj.level; } else if (that.conf.dnd.ofs == 0 || that.conf.dnd.ofs == 2) { // sibling before/after if (that.conf.dnd.ofs == 0) { // before tobj.item.parentNode.insertBefore(obj.item, tobj.item); } else if (tobj.item.nextSibling != null) { // after tobj.item.parentNode.insertBefore(obj.item, tobj.item.nextSibling); } else { // after tobj.item.parentNode.appendChild(obj.item); } obj.pId = tobj.pId; levelOfs = tobj.level-obj.level; } // update nested if level changed if (levelOfs != 0) { that.conf.dnd.kids[obj.id] = true; for (var a in that.conf.dnd.kids) { that.items[a].level += levelOfs; that._refreshItemHtml(a, (that.items[a].kids == true), true); } } // 4) check parent's kids area and remove if empty if (pobj != null && pobj.kids == true && pobj.item.lastChild.firstChild.childNodes.length == 0) { that._clearKidsNode(pobj.id) pobj.opened = false; } obj = tobj = pobj = null; that._fixAreaWidth(); that._callPublicEvent("onDrop", [that.conf.dnd.drop.id, that.conf.dnd.drop.pId, that.conf.dnd.drop.index]); } } } window.dhx4.zim.clear(that.conf.dnd.zi); that.conf.dnd = null; } this._dndOnContextMenu = function(e) { if (that.conf.dnd.inited == true) { e = e||event; e.cancelBubble = true; if (e.preventDefault) e.preventDefault(); e.returnValue = false; return false; } } // events this._dndInitEvents = function() { if (typeof(window.addEventListener) == "function") { window.addEventListener("mousemove", this._dndOnMouseMove, false); window.addEventListener("mouseup", this._dndOnMouseUp, false); window.addEventListener("contextmenu", this._dndOnContextMenu, false); } else { document.body.attachEvent("onmousemove", this._dndOnMouseMove); document.body.attachEvent("onmouseup", this._dndOnMouseUp); document.body.attachEvent("oncontextmenu", this._dndOnContextMenu); } } this._dndUnloadEvents = function() { if (typeof(window.addEventListener) == "function") { window.removeEventListener("mousemove", this._dndOnMouseMove, false); window.removeEventListener("mouseup", this._dndOnMouseUp, false); window.removeEventListener("contextmenu", this._dndOnContextMenu, false); } else { document.body.detachEvent("onmousemove", this._dndOnMouseMove); document.body.detachEvent("onmouseup", this._dndOnMouseUp); document.body.detachEvent("oncontextmenu", this._dndOnContextMenu); } } // dragged object this._dndInitDraggedObj = function() { this.conf.dnd.dragged = document.createElement("DIV"); this.conf.dnd.dragged.className = "dhxtreeview_dragged_obj_"+this.conf.skin; this.conf.dnd.dragged.style.zIndex = window.dhx4.zim.reserve(this.conf.dnd.zi); document.body.appendChild(this.conf.dnd.dragged); // this.conf.dnd.dragged.innerHTML = this.getItemText(this.conf.dnd.id); } this._dndAdjustDraggedObj = function() { this.conf.dnd.dragged.style.left = this.conf.dnd.x + this.conf.dnd.ofs_x + 12 + "px"; this.conf.dnd.dragged.style.top = this.conf.dnd.y + this.conf.dnd.ofs_y + 18 + "px"; } this._dndUnloadDraggedObj = function() { if (this.conf.dnd.dragged != null) { document.body.removeChild(this.conf.dnd.dragged); this.conf.dnd.dragged = null; } } // target node ui this._dndUpdateTargetCss = function(id, mode) { var t = this.items[id].item.childNodes[0]; if (this.conf.dnd.ofs == null) { mode = false; } if (mode == true) { t.className = String(t.className).replace(/(\s*dhxtreeview_drop_\d)?$/i, " dhxtreeview_drop_"+this.conf.dnd.ofs); // if (t.nextSibling == null || t.nextSibling.className.match(/dhxtreeview_drop_preview/) == null) { var k = document.createElement("DIV"); k.className = "dhxtreeview_drop_preview"; k.style.left = t.lastChild.previousSibling.style.left; if (t.nextSibling == null) { t.parentNode.appendChild(k); } else { t.parentNode.insertBefore(k, t.nextSibling); } k = null; } t.nextSibling.className = String(t.nextSibling.className).replace(/(\s*dhxtreeview_drop_\d)?$/i, " dhxtreeview_drop_"+this.conf.dnd.ofs); } else if (t.className.match(/dhxtreeview_drop_\d/) != null) { t.className = String(t.className).replace(/\s*dhxtreeview_drop_\d/gi, ""); // if (t.nextSibling != null && t.nextSibling.className.match(/dhxtreeview_drop_preview/) != null) { t.parentNode.removeChild(t.nextSibling); } } t = null; } // cache for kids items, dnd can't be performed this._dndCollectKids = function(pId) { for (var a in this.items) { if (this.items[a].pId == pId) { this.conf.dnd.kids[a] = true; if (this.items[a].kids == true) this._dndCollectKids(a); } } } this._dndCollectIndexes = function(node) { for (var q=0; q
"; } else { this._iconUpdate(id); } };