//Copyright (C) Ivanov I.M. //Site: http://www.tiptopcity.com/ //Элемент дерева (меню) //node - Сам XML узел (Из чего создан) //tree - Владелец function TTreeNode(node,tree) { //Присвоить текст документа соответствующему HTML элементу this.setCaption=function(val) { getCdata(this.node).nodeValue=val; var obj=document.getElementById(this.tree.m_pr+'text'+this.node.getAttribute("htmlid")); if(obj) { obj.innerHTML=" "+val+"\u00A0"; } }; //Получить путь к данному узлу в виде строки this.getTreePath=function() { var n=this; var c=''; while(n!=null) { if(n.treeid=='' || n.fid=='') break; //Чтоб пропустить корень дерева c=n.treeid+';'+n.fid+';'+c; n=n.parent; } return c; }; //Параметр из базы/XML по имени this.getParam = function(name) { for (var i = 0; i < this.params.length; i++) { if(this.params[i][0]==name) return this.params[i][1]; } return ''; }; this.htmlid=getUID(); //HTML id this.obj=null; //User data this.node=node; //XML node this.tree=tree; //Owner this.parent=null; //Родительский TTreeNode this.childs=new Array(); //Дочерние узлы TTreeNode this.params=new Array(); //Параметры для под узлов this.label=''; this.c='1'; //'1' то есть дети а если childs.length=0 то они ещё неподгружены this.wch=false; //Ждём ли мы прихода детей this.treeid=''; //Идентификатор ветки дерева this.fid=''; //Идентификатор записи this.ddl=false; //Раскрывать ли как выпадающий список в низ (drop down list) } /** Для меню должно подгружаться видемый и все не видимые под меню * v_obj - main html object, * v_scr - server script, * v_imgpth - path to images (TODO удалить) * v_treepath - Путь с которого отображать элементы дерева */ function TMenu(v_obj,v_scr,v_treepath) //Горизонтальное меню { // Начать загрузку данны this.Start=function() { //if(typeof(this.m_treepath)=="undefined") this.m_treepath='-1'; var xml=''; this.callServer(this.m_scr,xml); }; //отправить XML запрос на сервер this.callServer=function(url,xmlString) { if(url=='' || xmlString=='') return; var call=new myXMLHttpRequest(this); call.callServer(url,xmlString); }; //Построить дерево объектов TTreeNode из XML файла рекурсией (TODO XML потом удалять) //nOs - родительский объект //nTs - родительский XML this.buildTree=function(nOs,nTs) { var nT=nTs.firstChild; while(nT!=null) { if(nT.nodeName=="tree") { var nO=new TTreeNode(nT,this); nO.label=getCdataValue(nT); nO.c=nT.getAttribute("c"); nO.treeid=nT.getAttribute("treeid"); nO.fid=nT.getAttribute("fid"); // getCdata(findNodeOnAttribute(np, 'param','n',n.getAttribute('ObjectID'))).nodeValue; nO.ddl=(nT.getAttribute("ddl") == "1"); //Переписываем параметры для под узлов var nC=findNode(nT,'columns'); if(nC!=null) nC=nC.firstChild; while(nC!=null) { if(nC.nodeName=='param') { var len=nO.params.length; nO.params.push(new Array()); nO.params[len][0]=nC.getAttribute('n'); nO.params[len][1]=getCdataValue(nC); } nC=nC.nextSibling; } nO.parent=nOs; nOs.childs.push(nO); this.m_tn.push(nO); nT.setAttribute("htmlid",nO.htmlid); //проставить уникальные HTML ID для детей узла //!!!Рекурсия!!! this.buildTree(nO,nT); } nT=nT.nextSibling; } }; //Найти TTreeNode узел по его htmlid this.findNode=function(htmlid, treeid, fid) { if(typeof(htmlid)=='undefined') htmlid=''; if(typeof(treeid)=='undefined') treeid=''; if(typeof(fid)=='undefined') fid=''; for(var i=0;i2) { ptn=this.findNode('',mpath[mpath.length-3],mpath[mpath.length-2]); this.m_treepath=''; } } if(ptn==null) ptn=this.findNode(htmlid,'',''); //Ищем ищем родительскую кнопку чтоб задать положение для контейнера var btn=document.getElementById(this.m_pr+htmlid+'bt'); //Кнопка родитель var cnt=document.getElementById(this.m_pr+htmlid+'tb'); //Контейнер для создаваемых кнопок delChild(cnt); //Удалить дочерние HTML элементы из контейнера if(cnt==null) //Если контейнер не создан создаём его { cnt=document.createElement('div'); cnt.setAttribute('id',this.m_pr+htmlid+'tb'); cnt.style.cssText="display: inline-block; position: absolute; z-index: 999;"; if(btn!=null) //устанавливаем положение контейнера и задаём в качерстве родителя кнопку { var crd_m=ElemCoords(this.m_obj); var coord=ElemCoords(btn); coord.x=coord.x-crd_m.x; coord.y=coord.y-crd_m.y; if(ptn.ddl) //Если нужно отобразить как выпадающий список те. в низу { cnt.style.left='0px'; cnt.style.top=parseInt(btn.offsetHeight)+'px'; }else //Если как меню (TODO Если как дерево можно добавить) { //if(tn.node.parentNode.parentNode.nodeName!='tree') //{ // coord.x+=parseInt(this.offsetWidth) // coord.y+=parseInt(this.offsetHeight) //}else //{ coord.x+=parseInt(btn.offsetWidth); //coord.y+=parseInt(this.offsetHeight) //} cnt.style.left=coord.x+'px'; cnt.style.top=coord.y+'px'; //cnt.style.display='inline-block'; //btn.appendChild(cnt); //Кнопка будет владельцем контейнера } } this.m_obj.appendChild(cnt); } if(ptn.wch) //TODO проверить нужно или нет здесь { cnt.innerHTML=' Подождите пожалуйста...'; return; } for(var i=0;i
  ${name}  
'; str=str.replace(/\${path}/g, tn.getTreePath()); str=str.replace(/\${hash}/g, crc32(tn.getTreePath())); str=str.replace(/\${name}/g, tn.label); str=str.replace(/\${none}/g, tn.c=='1' ? 'block' : 'none'); for (var itn = 0; itn < tn.params.length; itn++) { if(tn.params[itn][1]!='') { str=str.replace(new RegExp("\\${"+tn.params[itn][0]+"}",'g'), tn.params[itn][1]); } } str=str.replace(/\${url}/g, crc32(tn.getTreePath())); //Если узел в пути отмечаем эту кнопку if(this.m_path.indexOf(tn.treeid+';'+tn.fid+';')>=0) { str=str.replace(/\${select}/g, 'text-decoration: underline;'); } cdiv.innerHTML=str; cdiv.onmouseover=function(tn,thiz) { return function() { tn.tree.m_hide=0; //чтоб отменить функцию скрытия меню при наведении //Строим массив TTreeNode от выделеного в верх по дереву var tmp=new Array(); var pn=tn;//.parent; while(pn!=null) { tmp.push(pn); pn=pn.parent; } //Скрываем все элементы кроме родителей выделеного for(var i=0;i' for(var i=0;i'; } xmlstring+=''; tn.tree.callServer(tn.tree.m_scr,xmlstring); } thiz.createList(tn.htmlid); //Строим подменю }; }(tn,this); cdiv.onmouseout=function(tn) { return function() { tn.tree.m_hide=tn.htmlid; //После потери фокуса ждём пол секунды и выполняем функцию по скрытию элементов setTimeout(function(tn){ return function(){ if(tn.tree.m_hide==tn.htmlid) { for(i=0;i
  ${name}  
'; str=str.replace(/\${path}/g, this.m_tn[this.m_tn.length-1].getTreePath()); str=str.replace(/\${name}/g, getCdataValue(nodeTree)); str=str.replace(/\${none}/g, nodeTree.getAttribute("c")=='1' ? 'block' : 'none'); //создаём кнопку меню cdiv=document.createElement('div'); cdiv.style.cssText="width: 100%; display: inline-block;"; pdiv.appendChild(cdiv); if(nodeTree.getAttribute('visible')=='0') cdiv.style.display='none'; cdiv.innerHTML=str; cdiv.onmouseover=function(tn,cdiv,thiz) { return function() { tn.tree.m_hide=0; var tmp=new Array(); var pn=tn.node.parentNode; while(true) { if(pn==null || pn.nodeName!='tree') break; tmp.push(tn.tree.m_pr+pn.getAttribute("htmlid")+'tb'); pn=pn.parentNode; } //Скрываем все элементы кроме родителей выделеного for(i=0;i'+getXMLNodeSerialisation(nodeParameters)+''; tn.tree.callServer(tn.tree.m_scr,xmlstring); } tb.style.left=coord.x+'px'; tb.style.top=coord.y+'px'; tb.style.display='inline-block'; //При наведении запрашиваем под узлы если они ещё не загружены и небыли запрошены //var pnode=findFirstNodeOnAttribute(tb,'nobr','id','qwerty') /*nod=tn.node.firstChild while(nod!=null) { if(nod.nodeName=='tree') { if(nod.getAttribute('c')=='1' && document.getElementById(tn.tree.m_pr+nod.getAttribute("htmlid")+'tb')==null) { fid=nod.getAttribute("fid") treeid=nod.getAttribute("treeid") nodeName=nod.getAttribute("t") nodeParameters=findFirstNode(nod,"columns") //если нет ни одного дочернего tree то запрашиваем данные иначе раскрываем список xmlstring=''+getXMLNodeSerialisation(nodeParameters)+''; tn.tree.callServer(tn.tree.m_scr,xmlstring) //TODO зделать табличку подождите пожалуйста } } nod=nod.nextSibling }*/ }; }(this.m_tn[this.m_tn.length-1],cdiv,this); cdiv.onmouseout=function(tn) { return function() { tn.tree.m_hide=tn.htmlid; setTimeout(function(tn){ return function(){ if(tn.tree.m_hide==tn.htmlid) { for(i=0;i'; this.m_scr=v_scr; this.m_treepath=v_treepath; // Стартовый путь this.m_htmlid=0; //Запрошеный пользователем htmlid //c - have child; fid - id from database this.XMLTree=CreateXMLDOC(''); this.m_root=new TTreeNode(null,this); //Корневой узел this.m_root.wch=true; //Признак ожидания детей this.m_tn=new Array(); //TTreeNode list this.m_tn.push(this.m_root); this.m_ls=new Array(); //listener list this.m_lsl=new Array(); //listener list load this.m_path=''; //путь для выделения (подсвечивания) кнопочек this.m_exp=false; this.m_hide=0; //Создаём самый верхний контейнер с 0м HTMLID var cnt=document.createElement('div'); cnt.setAttribute('id',this.m_pr+this.m_root.htmlid+'tb'); cnt.style.cssText="width: 100%; display: inline-block;"; cnt.innerHTML=' Подождите пожалуйста...'; this.m_obj.appendChild(cnt); } //v_obj - main html object, v_pr - html id prefix, v_scr - server script, v_pth - path to images function TTree(v_obj,v_pr,v_scr,v_pth,v_imgsize) //Дерево { //Запускает запрос корня дерева с сервера this.Start=function() { xmlstring=''; this.callServer(this.m_scr,xmlstring); }; //отправить XML на сервер this.callServer=function(url,xmlString) { var call=new myXMLHttpRequest(this); call.callServer(url,xmlString); }; this.processReqChange=function(xmlHttpRequest,url,xmlString) { if (typeof(xmlHttpRequest.readyState)=='undefined' || xmlHttpRequest.readyState == 4) { if(typeof(xmlHttpRequest.status)=='undefined' || xmlHttpRequest.status == 200) // only if "OK" { if(typeof(xmlHttpRequest.responseXML)=='undefined' && xmlHttpRequest.contentType.match(/\/xml/)) //For IE XDomainRequest xmlHttpRequest.responseXML=CreateXMLDOC(xmlHttpRequest.responseText); //загрузился xml документ начинаем его разбирать (по id функции в документе) let xmldoc = xmlHttpRequest.responseXML; if(xmldoc==null){ alert2(_('Alert'),_('Wrong_XML_document')+"!\n"+xmlHttpRequest.responseText); return; } let node = xmldoc.documentElement; if((node==null)||(node.getAttribute("fn")==null)) alert2(_('Alert'),_('Error')+"\n"+_('No_data')+"!\n"+xmlHttpRequest.responseText); else { var fn = node.getAttribute("fn"); if (fn==0) { alert2(_('Alert'),findFirstNode(node,"#cdata-section").nodeValue); }else if (fn==1) { this.addNode(node); this.OpenTreeOnPath(this.m_path); }else alert2(_('Alert'),"Unknown function! fn=\""+fn+"\"" ); } }else { alert2(_('Alert'),_('Failed_to_get_data')+"\n URL: "+url+"\n" + xmlHttpRequest.statusText); } } }; //развернуть дерево создать либо удалить (если нет данных то подгрузить) //Результат true если уже загружен и false если ещё нет те отправили запрос на загрузку //v_o - 1 open 0 - close else invert this.openTree=function(htmlid,v_o) { var thetable=document.getElementById(this.m_pr+'table'+htmlid); if (thetable==null) return false; var node=findFirstNodeOnAttribute(this.XMLTree.documentElement,"tree","htmlid",htmlid); if(node==null) return false; if(node.getAttribute("c")!='1' && v_o==1) return true; //false //ищем ячейку "подождите пожалуйста" и удаляем её w=document.getElementById(this.m_pr+'pw'+htmlid); if(w!=null) w.parentNode.removeChild(w); if(thetable.rows.length<2)//развернуть дерево { if(node.getAttribute("o")==null) node.setAttribute ("o","0"); if(findFirstNode(node,"tree")==null) { //ячейка подождите пожалуйста thetr = thetable.insertRow(thetable.rows.length); thetr.setAttribute("id",this.m_pr+'pw'+htmlid); thetd = thetr.insertCell(thetr.cells.length); thetd.appendChild(document.createTextNode(" ")); thetd = thetr.insertCell(thetr.cells.length); thetd.innerHTML=' Подождите пожалуйста...'; fid=node.getAttribute("fid"); treeid=node.getAttribute("treeid"); nodeName=node.getAttribute("t"); nodeParameters=findFirstNode(node,"columns"); //если нет ни одного дочернего tree то запрашиваем данные иначе раскрываем список xmlstring=''+getXMLNodeSerialisation(nodeParameters)+''; this.callServer(this.m_scr,xmlstring); return false; } //добавляем таблицы var nodeTree=node.firstChild; while (nodeTree!=null) { if (nodeTree.nodeName=="tree") { hid=nodeTree.getAttribute("htmlid"); id=nodeTree.getAttribute("id"); iid=nodeTree.getAttribute("iid"); fid=nodeTree.getAttribute("fid"); o=nodeTree.getAttribute("o"); t=nodeTree.getAttribute("t"); var name=getCdataValue(nodeTree); thetr = thetable.insertRow(thetable.rows.length); thetd = thetr.insertCell(thetr.cells.length); thetd.appendChild(document.createTextNode(" ")); thetd = thetr.insertCell(thetr.cells.length); //thetd.setAttribute("width","100%") table=document.createElement('table'); table.style.cssText="border-spacing:0px; border-collapse: separate;"; table.setAttribute('border','0'); table.setAttribute("id",this.m_pr+"table"+hid); table.cellspacing=0; table.cellpadding=0; newRow=table.insertRow(0); //добавляем строку в созданной таблице newCell = newRow.insertCell(0); //в созданной строке добавляем столбец newCell.style.cssText="padding:0px;"; if(nodeTree.getAttribute("c")=="1") { img=document.createElement('img'); img.setAttribute("id",this.m_pr+"table"+hid+"f1"); if(o==1) { img.src=this.m_pth+'icons/minus.png'; img.setAttribute("alt","-"); } else { img.src=this.m_pth+'icons/plus.png'; img.setAttribute("alt","+"); }//рикунок + или - img.style.cssText="cursor: pointer;"; img.onclick=function(obj,val1){ return function(){ obj.openTree(val1); }; }(this,hid); }else { img=document.createElement('img'); img.src=this.m_pth+'icons/blank24.gif'; img.setAttribute("alt"," "); } newCell.appendChild(img); newCell = newRow.insertCell(1); newCell.style.cssText="padding:0px; width:100%; cursor: pointer; vertical-align: top;"; newCell.setAttribute('noWrap', 'true'); //Цвет и событие нажатия должно применяться к одному и томуже DOM объекту ! newCell.setAttribute("id",this.m_pr+'cell'+hid); //Для снятия выделения if(nodeTree.getAttribute("s")=="1") newCell.style.backgroundColor='#dddddd'; newCell.onmouseover=function(node){ return function(){ if(node.getAttribute("s")!="1") this.style.backgroundColor='#d1d1d1'; }; }(nodeTree); newCell.onmouseout=function(node){ return function(){ if(node.getAttribute("s")!="1") this.style.backgroundColor='transparent'; }; }(nodeTree); //Нажатие на текст узла (слушателю XML этого узла) nObj=null; for(var i=0;i1 && v_o!=1)//свернуть дерево { //удалить все строки в таблице кроме первой var tbl=document.getElementById(this.m_pr+'table'+htmlid); while (tbl.rows.length>1) tbl.tBodies[0].deleteRow(1); node.setAttribute ("o","0"); img=document.getElementById(this.m_pr+'table'+htmlid+'f1'); if(img!=null){ img.src=this.m_pth+'icons/plus.png'; img.setAttribute("alt","+"); } } return true; }; //add node to tree this.addNode=function(node) { if(node==null) return; var htmlid=node.getAttribute("htmlid"); //parent id var pnode=findFirstNodeOnAttribute(this.XMLTree,"tree","htmlid",htmlid); var nodeTree=node.firstChild; while (nodeTree!=null) { if(nodeTree.nodeName=="tree") { nodeTree.parentNode.removeChild(nodeTree); pnode.appendChild(nodeTree); this.m_tn[this.m_tn.length]=new TTreeNode(nodeTree,this); nodeTree.setAttribute("htmlid",this.m_tn[this.m_tn.length-1].htmlid); //проставить уникальные HTML ID для детей узла for(var i=0;iname" this.getTXTPath=function() { n=null; for(var i=0;i'+c; n=n.parentNode; } return c.substring(2,c.length-2); }; //Обновить детей заданного узла (TODO Доделать) this.updateNode=function(htmlid) { //var n=findFirstNodeOnAttribute(this.XMLTree.documentElement,"tree","htmlid",htmlid) //while(n.hasChildNodes()) n.removeChild(n.firstChild) //openTree(htmlid) }; //Раскрыть все элементы заданного узла this.expandAll=function(htmlid) { this.m_exp=true; //if (typeof htmlid == "undefined") htmlid = 1; //this.openTree(htmlid,1) //var n=findFirstNodeOnAttribute(this.XMLTree.documentElement,'tree','htmlid',htmlid); //openTree() }; //Свернуть все элементы заданного узла this.collapseAll=function(htmlid) { for(var i=0;i'; this.m_pr=v_pr; //Prefix for HTML ids this.m_scr=v_scr; this.m_pth=v_pth; this.m_imgsize=v_imgsize; //c - have child; fid - id from database this.XMLTree=CreateXMLDOC(''); this.m_tn=new Array(); //TTreeNode list this.m_ls=new Array(); //listener list this.m_lsl=new Array(); //listener list load this.m_path=''; this.m_exp=false; //ячейка подождите пожалуйста var thetable=document.getElementById(this.m_pr+'table0'); thetr = thetable.insertRow(thetable.rows.length); thetr.setAttribute("id",this.m_pr+'pw0'); thetd = thetr.insertCell(thetr.cells.length); thetd.appendChild(document.createTextNode(" ")); thetd = thetr.insertCell(thetr.cells.length); thetd.innerHTML=' Подождите пожалуйста...'; }