ui_engine.js 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829
  1. /*##############################################################################
  2. # Copyright (C) 2011 HPCC Systems.
  3. #
  4. # All rights reserved. This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as
  6. # published by the Free Software Foundation, either version 3 of the
  7. # License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ############################################################################## */
  17. var command;
  18. var component;
  19. var xmlDoc;
  20. var schemaRootNode;
  21. var objRootNode;
  22. var bAdd;
  23. var argsNodeName;
  24. function loadCommandInfo()
  25. {
  26. setModified(false);
  27. document.body.onbeforeunload = onBeforeUnloadDocument;
  28. component = document.getElementById('component').value;
  29. command = document.getElementById('command').value;
  30. if (typeof xmlSchema != 'undefined' && xmlSchema.documentElement)
  31. {
  32. var xpath = '/Components/' + component + '/Commands/' + command;
  33. var commandSchemaNode = xmlSchema.documentElement.selectSingleNode(xpath);
  34. argsNodeName = getAttribute(commandSchemaNode, 'argsNode', 'Arguments');
  35. schemaRootNode = commandSchemaNode.selectSingleNode(argsNodeName);
  36. if (schemaRootNode == null)
  37. {
  38. alert('No arguments node found in XML schema!');
  39. return;
  40. }
  41. }
  42. else
  43. {
  44. schemaRootNode = null;
  45. argsNodeName = 'Arguments';
  46. }
  47. var prevArgsDoc = document.getElementById("xmlPrevArgsDoc");
  48. if (prevArgsDoc)
  49. {
  50. xmlDoc = prevArgsDoc;
  51. objRootNode = prevArgsDoc.documentElement;
  52. if (schemaRootNode)
  53. {
  54. var captionObj = document.getElementById('pageCaption');
  55. if (captionObj)
  56. captionObj.innerText = expand_embedded_xpaths( captionObj.innerText, schemaRootNode, objRootNode, false);
  57. }
  58. }
  59. else
  60. objRootNode = null;
  61. var subCaptionObj = document.getElementById('pageSubCaption');
  62. if (subCaptionObj)
  63. {
  64. var subcaption = subCaptionObj.innerHTML;
  65. if (subcaption.indexOf('Loading,')==0)
  66. subCaptionObj.style.display = 'none';
  67. else
  68. if (prevArgsDoc && schemaRootNode)
  69. subCaptionObj.innerText = expand_embedded_xpaths( subcaption, schemaRootNode, objRootNode, false);
  70. }
  71. //alert(tableObj.outerHTML);
  72. //alert(document.forms[0].outerHTML);
  73. initFixedTables();
  74. ms_initializeAll();
  75. var pageBody = document.getElementById('pageBody');
  76. if (pageBody)
  77. pageBody.focus();
  78. if (typeof onLoadCustom != 'undefined')
  79. onLoadCustom();
  80. }
  81. function createTable(id, className, border, width)
  82. {
  83. tableObj = document.createElement('table');
  84. tableObj.id = id;
  85. if (border)
  86. tableObj.border = border;
  87. if (className)
  88. tableObj.className='sort-table';
  89. if (width)
  90. tableObj.width = width;
  91. return tableObj;
  92. }
  93. function populateTable(tableObj, targetNode, schemaNode, xpath)
  94. {
  95. //make header
  96. createColumnHeaders(tableObj, null, targetNode, schemaNode, xpath, undefined);
  97. addTableRows(tableObj, targetNode, schemaNode, xpath, null);
  98. //create buttons
  99. var xpathBtns = (schemaNode == schemaRootNode && argsNodeName == '.') ? 'Buttons' : '../Buttons';
  100. var btnsNode = schemaNode.selectSingleNode(xpathBtns);
  101. if (btnsNode || schemaNode == schemaRootNode)
  102. {
  103. createButtons(tableObj, btnsNode, false);
  104. if (tableObj.offsetHeight > 600)
  105. createButtons(tableObj, btnsNode, true);
  106. }
  107. }
  108. function createColumnHeaders(tableObj, row, targetNode, schemaNode, xpath, nTableRows)
  109. {
  110. //insert checkbox column header unless checkboxes are not desired
  111. //
  112. var xpath2;
  113. if (schemaNode == schemaRootNode)
  114. xpath2 = null;
  115. else
  116. xpath2 = xpath ? xpath + '.' + schemaNode.nodeName : schemaNode.nodeName;
  117. var maxOccurs = getAttribute(schemaNode, 'maxOccurs', null);
  118. if (maxOccurs)//each table column is an attribute of a target node
  119. {
  120. if (maxOccurs == 'unbounded')
  121. {
  122. var checkboxes = getAttributeBool(schemaNode, 'checkboxes', true);
  123. if (checkboxes)
  124. {
  125. if (!row)
  126. row = tableObj.insertRow();
  127. col = document.createElement('th');
  128. col.width = '10';
  129. row.appendChild(col);
  130. //make multi selection checkbox if multiple selection is desired
  131. //
  132. var multiselect = getAttributeBool(schemaNode, 'multiselect', false);
  133. if (multiselect)
  134. {
  135. var childObjNodes = targetNode.selectNodes(schemaNode.nodeName);
  136. nTableRows = childObjNodes.length;
  137. var multiselect = ms_create( tableObj.id, onRowCheck )
  138. if (nTableRows > 1)
  139. {
  140. //insert checkbox
  141. var bChecked = getAttributeBool(schemaNode, 'checked', false);
  142. //var cbName = xpath2 + ".checkbox";
  143. var s = new Array();
  144. var i=0;
  145. s[i++] = '<input type="checkbox" value="1"';
  146. if (bChecked)
  147. s[i++] = ' checked="true"';
  148. s[i++] = ' title="Select or unselect all items"';
  149. s[i++] = ' onclick="ms_setAll(this, \'';
  150. s[i++] = multiselect.tableId;
  151. s[i++] = "',";
  152. s[i++] = multiselect.n_column;
  153. s[i++] = ')"> </input>';
  154. col.innerHTML = s.join('');
  155. col.id = multiselect.makeSetAllId(true);
  156. }
  157. }
  158. }
  159. }
  160. else
  161. if (xpath == null)//if this node does not recur then we don't need column headers for this node
  162. return;
  163. //descend to the children of schemaNode
  164. //
  165. var childObjNode = targetNode ? targetNode.selectSingleNode(schemaNode.nodeName) : null;
  166. for ( var childSchemaNode = schemaNode.firstChild;
  167. childSchemaNode;
  168. childSchemaNode = childSchemaNode.nextSibling)
  169. {
  170. var name = childSchemaNode.nodeName;
  171. if (name != "#comment" && name != 'Buttons')//ignore comments and buttons
  172. {
  173. var maxOccurs = getAttribute(childSchemaNode, 'maxOccurs', null);
  174. if (maxOccurs=='1')
  175. createColumnHeaders(tableObj, row, childObjNode, childSchemaNode, xpath2, nTableRows);
  176. else
  177. {
  178. if (maxOccurs == null)//an attribute
  179. {
  180. var viewType = getAttribute(childSchemaNode, 'viewType', null);
  181. if (viewType != 'hidden')
  182. {
  183. if (!row)
  184. row = tableObj.insertRow();
  185. var thObj = document.createElement('th');
  186. var caption = getAttribute(childSchemaNode, 'caption', name);
  187. var innerText = caption;
  188. //if multiple selection is desired on this column
  189. //
  190. if ((nTableRows == undefined || nTableRows > 1) &&
  191. getAttributeBool(childSchemaNode, 'multiselect', false))
  192. {
  193. //if there are multiple rows in this table
  194. //create a multiple selection object to manage this column
  195. //
  196. var multiselect = ms_create( tableObj.id, onColumnCheck, null, row.cells.length )
  197. thObj.id = multiselect.makeSetAllId(true);
  198. var dataNode = childObjNode ? childObjNode.selectNodes(childSchemaNode.nodeName)[0] : null;
  199. var dataType = getAttribute(childSchemaNode, 'dataType', null);
  200. var input = createInputControlForNode(xpath, dataNode, childSchemaNode, dataType, viewType, multiselect, true);
  201. input.style.display = 'none';
  202. multiselect.inputTag = input.tagName;
  203. multiselect.inputType = input.type;
  204. var s = new Array();
  205. var i = 0;
  206. s[i++] = "<a href='' onClick=\"toggleMultiSelect( '";
  207. s[i++] = tableObj.id;
  208. s[i++] = "',";
  209. s[i++] = row.cells.length;
  210. s[i++] = ", true); return false;\"";
  211. s[i++] = "title='Set all items in this column...'>";
  212. s[i++] = caption
  213. s[i++] = "</a>"
  214. thObj.innerHTML = s.join('');
  215. thObj.appendChild(input);
  216. innerText = null;
  217. }
  218. if (innerText)
  219. thObj.innerText = innerText;
  220. row.appendChild(thObj);
  221. }
  222. }
  223. }
  224. }
  225. }
  226. }
  227. }
  228. function toggleMultiSelect( tableId, column, bTopOfTable )
  229. {
  230. var ms = ms_lookupByTableAndColumn(tableId, column);
  231. if (!ms.b_initialized)
  232. ms.initialize();
  233. var id = ms.makeSetAllId(bTopOfTable) + '_I';
  234. var o = document.getElementById( id );
  235. if (o)
  236. {
  237. var bShow = o.style.display == 'none';
  238. o.style.display = bShow ? 'block' : 'none';
  239. }
  240. }
  241. function createButtons(tableObj, btnsNode, addOnTop)
  242. {
  243. //create a blank line for vertical spacing
  244. //
  245. var nCols = findMaxTableColumns(tableObj);
  246. if (nCols < 1)
  247. nCols = 1;
  248. //insert blank line for vertical separation
  249. //
  250. if (addOnTop)
  251. {
  252. row = tableObj.insertRow(0);
  253. blankRow = tableObj.insertRow(1);
  254. }
  255. else
  256. {
  257. blankRow = tableObj.insertRow(-1);
  258. row = tableObj.insertRow(-1);
  259. }
  260. cell = blankRow.insertCell();
  261. cell.height = '15px';
  262. cell.colSpan= nCols;
  263. cell = row.insertCell();
  264. cell.align="center";
  265. cell.colSpan= nCols;
  266. var innerHTML = '';
  267. //if (!btnsNode || getAttributeBool(btnsNode, 'showResetButton', true))
  268. // innerHTML += '<input type="reset" value="Reset"/>&nbsp';
  269. if (btnsNode)
  270. {
  271. for (var btn = btnsNode.firstChild; btn; btn=btn.nextSibling)
  272. {
  273. if (innerHTML != '')
  274. innerHTML += '&nbsp;&nbsp;';
  275. innerHTML += btn.xml;
  276. }
  277. }
  278. else
  279. {
  280. if (innerHTML != '')
  281. innerHTML += '&nbsp;&nbsp;';
  282. var onClickOKBtn = btnsNode ? getAttribute(btnsNode, 'OnClickOKBtn', null) : null;
  283. var btnName = "OK" + (addOnTop ? "1" : "");
  284. if (onClickOKBtn)
  285. innerHTML += '<input type="button" name="' + btnName + '" value="OK" onclick="' + onClickOKBtn + '"/>';
  286. else
  287. innerHTML += '<input type="submit" name="' + btnName + '" value="Submit"/>';
  288. }
  289. cell.innerHTML = innerHTML;
  290. }
  291. function addTableRows(tableObj, objNode, schemaNode, xpath, lastRow)
  292. {
  293. var name = schemaNode.nodeName;
  294. if (name == "#comment" || name == 'Buttons')//ignore comments
  295. return;
  296. var maxOccurs = getAttribute(schemaNode, 'maxOccurs', null);
  297. var xpath2;
  298. if (xpath)
  299. xpath2 = xpath + '.' + name;
  300. else
  301. xpath2 = (schemaNode == schemaRootNode && argsNodeName=='Arguments') ? null : name;
  302. var showHideRow = null;
  303. if (maxOccurs == "unbounded")
  304. {
  305. if (tableObj.id != xpath2)
  306. {
  307. //create another table that would occupy entire cell of parent table's row
  308. var childTableObj = createTable(xpath2, 'sort-table', 1, '100%');
  309. var row = tableObj.insertRow(-1);//insert new row
  310. var cell = row.insertCell();
  311. cell.appendChild(childTableObj);
  312. populateTable(childTableObj, objNode, schemaNode, xpath);
  313. }
  314. else
  315. {
  316. var bRowCheckbox = getAttributeBool(schemaNode, 'checkboxes', true);
  317. var checked = getAttributeBool(schemaNode, 'checked', false);
  318. //append rows in table
  319. var targetNodes = objNode.selectNodes(name);
  320. var nNodes = targetNodes.length;
  321. for (var i=0; i<nNodes; i++)
  322. {
  323. var row = tableObj.insertRow(-1);//insert after last row
  324. var lastRowIndex = tableObj.lastRowIndex ? parseInt(tableObj.lastRowIndex) + 1 : 0;
  325. updateItemList(tableObj, lastRowIndex, null);
  326. var showHideRow = populateTableRow( tableObj, row, targetNodes[i],
  327. schemaNode, xpath2, bRowCheckbox,
  328. checked == '1' || checked == 'true');
  329. if (showHideRow)
  330. {
  331. var newRow = tableObj.insertRow(-1);//insert after last row
  332. newRow.id = row.id + '.toggle';
  333. newRow.style.display = 'none';
  334. var cell = newRow.insertCell();
  335. cell.colSpan = row.cells.length - (bRowCheckbox ? 1 : 0);
  336. cell.style.textAlign = 'left';
  337. //cell.innerHTML = showHideRow['node'].text.replace( new RegExp('\n', 'g'), '<br/>');
  338. cell.innerText = showHideRow['node'].text;
  339. }//if
  340. }//for
  341. }
  342. }
  343. else
  344. if (maxOccurs == "1" || schemaNode == schemaRootNode)
  345. {
  346. var targetNode = objNode.selectSingleNode(name);
  347. if (!targetNode)
  348. {
  349. targetNode = xmlDoc.createElement(name);
  350. objNode.appendChild(targetNode);
  351. }
  352. var caption = getAttribute(schemaNode, 'caption', null);
  353. var captionCell = null;
  354. if (caption && (argsNodeName !='.' || schemaNode != schemaRootNode))
  355. {
  356. //if this table has at least one line then leave a blank line
  357. if (tableObj.rows.length && tableObj.rows.length > 0)
  358. {
  359. var row = tableObj.insertRow(-1);
  360. var cell = document.createElement('td');
  361. cell.height = 20;
  362. row.appendChild(cell);
  363. }
  364. //create another table that would occupy entire cell of parent table's row
  365. var childTableObj = createTable(xpath2, null, 0, '100%');
  366. //add caption for this child table
  367. //
  368. row = childTableObj.insertRow();
  369. captionCell = row.insertCell();
  370. captionCell.innerHTML = '<h3>' + caption + '</h3>';
  371. captionCell.align = 'left';
  372. captionCell.noWrap= true;
  373. row = tableObj.insertRow();//insert new row
  374. cell = row.insertCell();
  375. cell.noWrap = true;
  376. cell.appendChild(childTableObj);
  377. tableObj = childTableObj;
  378. }
  379. for ( var childSchemaNode = schemaNode.firstChild;
  380. childSchemaNode;
  381. childSchemaNode = childSchemaNode.nextSibling)
  382. {
  383. var childName = childSchemaNode.nodeName;
  384. if (childName != "#comment" && childName != 'Buttons')//ignore comments and buttons
  385. {
  386. var showHideRow2 = addTableRows(tableObj, targetNode, childSchemaNode, xpath2, null);//false, false
  387. if (showHideRow2)
  388. showHideRow = showHideRow2;
  389. }
  390. }
  391. if (captionCell)
  392. captionCell.colSpan = findMaxTableColumns(childTableObj);
  393. }
  394. else//an attribute
  395. {
  396. var caption = getAttribute(schemaNode, 'caption', name);
  397. var row = tableObj.insertRow();
  398. var cell = document.createElement('td');
  399. //cell.style.padding=0;
  400. cell.innerHTML = '<b>' + caption + '</b>';
  401. cell.width = '1%';
  402. row.appendChild(cell);
  403. cell = document.createElement('td');
  404. cell.innerHTML = '<b>:</b>';
  405. cell.width = '1%';
  406. row.appendChild(cell);
  407. var targetNode = objNode.selectSingleNode(name);
  408. if (!targetNode)
  409. {
  410. targetNode = xmlDoc.createElement(name);
  411. objNode.appendChild(targetNode);
  412. }
  413. showHideRow2 = insertAttribNodeInRow(tableObj, row, targetNode, schemaNode, xpath, 'left');
  414. var ncells= row.cells.length;
  415. row.cells[ncells-1].width = '98%';
  416. if (showHideRow2)
  417. showHideRow = showHideRow2;
  418. }
  419. }
  420. function populateTableRow(tableObj, row, domNode, schemaNode, strXPath, bRowCheckbox, bChecked)
  421. {
  422. var nodeName = domNode.nodeName;
  423. var lastRowIndex = tableObj.lastRowIndex ? parseInt(tableObj.lastRowIndex) + 1 : 0;
  424. tableObj.lastRowIndex = lastRowIndex.toString();
  425. var showHideRow = null;
  426. if (bRowCheckbox)
  427. {
  428. row.id = strXPath + '.' + tableObj.lastRowIndex;
  429. //insert checkbox
  430. var col = row.insertCell();
  431. var cbName = strXPath + ".checkbox";
  432. //it is much faster to join a string array than assign concatenating strings
  433. //
  434. var innerHTML = new Array();
  435. var i = 0;
  436. innerHTML[i++] = '<input type="checkbox" name="';
  437. innerHTML[i++] = cbName;
  438. innerHTML[i++] = '" value="1"';
  439. if (bChecked)
  440. innerHTML[i++] = ' checked="true"';
  441. var multiselect = ms_lookupByTableAndColumn(tableObj.id, 0);
  442. if (multiselect)
  443. {
  444. innerHTML[i++] = ' onclick="ms_onChange(this, \'';
  445. innerHTML[i++] = multiselect.tableId;
  446. innerHTML[i++] = "',";
  447. innerHTML[i++] = multiselect.n_column;
  448. innerHTML[i++] = ')"';
  449. }
  450. innerHTML[i++] = '> </input>';
  451. col.innerHTML = innerHTML.join('');
  452. }
  453. for ( var childSchemaNode = schemaNode.firstChild;
  454. childSchemaNode;
  455. childSchemaNode = childSchemaNode.nextSibling)
  456. {
  457. var name = childSchemaNode.nodeName;
  458. if (name != "#comment" && name != 'Buttons')
  459. {
  460. var showHideRow2 = insertCellInRow(tableObj, row, domNode, childSchemaNode, strXPath + '.' + tableObj.lastRowIndex);
  461. if (showHideRow2)
  462. showHideRow = showHideRow2;
  463. }
  464. }
  465. return showHideRow;
  466. }
  467. function insertCellInRow(tableObj, row, targetNode, schemaNode, strXPath)
  468. {
  469. var showHideRow = null;
  470. var maxOccurs = getAttribute(schemaNode, 'maxOccurs', null);
  471. if (maxOccurs == "unbounded")
  472. {
  473. //create another table that would occupy entire cell of parent table's row
  474. var xpath2 = strXPath ? strXPath + '.' + schemaNode.nodeName : schemaNode.nodeName;
  475. var childTableObj = createTable(xpath2, null, 0, '100%');
  476. populateTable(childTableObj, targetNode, schemaNode, strXPath);
  477. var cell = row.insertCell();
  478. cell.appendChild(childTableObj);
  479. return;
  480. }
  481. var name = schemaNode.nodeName;
  482. var childNode = null;
  483. if (maxOccurs == null)//see if this is for innerText
  484. {
  485. var dataType = getAttribute(schemaNode, 'dataType', null);
  486. if (dataType == 'innerText')
  487. childNode = targetNode;
  488. }
  489. if (childNode == null)
  490. {
  491. childNode = targetNode.selectSingleNode(name);
  492. if (childNode == null)
  493. {
  494. childNode = xmlDoc.createElement(name);
  495. targetNode.appendChild(childNode);
  496. }
  497. }
  498. if (maxOccurs == "1")
  499. {
  500. var xpath = strXPath ? (strXPath + '.' + name) : name;
  501. for ( var childSchemaNode = schemaNode.firstChild;
  502. childSchemaNode;
  503. childSchemaNode = childSchemaNode.nextSibling)
  504. {
  505. var childName = childSchemaNode.nodeName;
  506. if (childName != '#comment' && childName != 'Buttons')//ignore comments
  507. {
  508. var showHideRow2 = insertCellInRow(tableObj, row, childNode, childSchemaNode, xpath);
  509. if (showHideRow2)
  510. showHideRow = showHideRow2;
  511. }
  512. }
  513. }
  514. else //attribute
  515. showHideRow = insertAttribNodeInRow(tableObj, row, childNode, schemaNode, strXPath);
  516. return showHideRow;
  517. }
  518. function insertAttribNodeInRow(tableObj, row, targetNode, schemaNode, strXPath, alignment)
  519. {
  520. var showHideRow = null;
  521. //create an HTML object corresponding to this element
  522. //
  523. var dataType = getAttribute(schemaNode, 'dataType', null);
  524. var viewType = getAttribute(schemaNode, 'viewType', null);
  525. var multiselect = ms_lookupByTableAndColumn( tableObj.id, row.cells.length );
  526. var input = createInputControlForNode(strXPath, targetNode, schemaNode, dataType, viewType, multiselect, false);
  527. var inputType = input.type;
  528. var disabled = getAttribute(schemaNode, 'disabled', null);
  529. var b_static = false;
  530. if (inputType == "hidden")
  531. {
  532. row.appendChild(input);
  533. b_static = viewType && (viewType.indexOf('static')==0 || viewType == 'tooltip');
  534. if (!b_static)
  535. return null;
  536. }
  537. if (disabled == 'true') {
  538. input.disabled = true;
  539. }
  540. if (viewType == 'showHideRowBtn')
  541. {
  542. if (targetNode.text == '')
  543. input.disabled = true;
  544. else
  545. {
  546. showHideRow = new Array();
  547. showHideRow['node'] = targetNode;
  548. showHideRow['schemaNode'] = schemaNode;
  549. input.onclick = new Function('onShowHideRow(this, "' + row.id + '.toggle")');
  550. }
  551. input2 = document.createElement('input');
  552. input2.id = strXPath ? (strXPath + '.' + targetNode.nodeName) : targetNode.nodeName;
  553. input2.name = input2.id;
  554. input2.type = 'hidden';
  555. input2.value = targetNode.text;
  556. if (input2.value=="")
  557. input2.value = getAttribute(schemaNode, 'default', '');
  558. row.appendChild(input2);
  559. }
  560. var cell = row.insertCell(row.cells.length);
  561. var align = getAttribute(schemaNode, 'align', null);
  562. if (align)
  563. cell.align = align;
  564. else
  565. if (alignment)
  566. cell.align = alignment;
  567. var vAlign = getAttribute(schemaNode, 'valign', null);
  568. if (vAlign)
  569. cell.vAlign = vAlign;
  570. if (inputType != "checkbox" && inputType != "file" && inputType != "button" && inputType != "hidden")
  571. {
  572. if (getAttribute(schemaNode, 'noWrap', null))
  573. cell.noWrap = true;
  574. var cellWidth = getAttribute(schemaNode, 'width', null);
  575. if (cellWidth)
  576. cell.width = cellWidth;
  577. else
  578. {
  579. /*
  580. if ((inputType != 'text' || !getAttribute(schemaNode, 'size', null)) && row.rowIndex > 0)
  581. {
  582. var firstRow = tableObj.rows[0].cells[;
  583. input.width=cell.clientWidth ? cell.clientWidth : 70;
  584. }
  585. */
  586. }
  587. }
  588. if (b_static)
  589. {
  590. if (viewType == 'tooltip')
  591. {
  592. var len = targetNode.text.length;
  593. if (len <= 7)
  594. cell.innerText = targetNode.text;
  595. else
  596. {
  597. cell.innerText = targetNode.text.substring(0,4) + '...';
  598. cell.onmouseover=function(){ EnterContent('ToolTip', null, targetNode.text, true); Activate();};
  599. cell.onmouseout=deActivate;
  600. }
  601. }
  602. else if (dataType == 'boolean')
  603. {
  604. cell.innerText = targetNode.text;
  605. }
  606. else if (targetNode.text != '')
  607. {
  608. var colonPos = viewType.indexOf(':');
  609. if (colonPos == -1)//not found
  610. cell.innerText = targetNode.text;
  611. else
  612. {
  613. var optionsArray = viewType.substring(colonPos+1).split('|');
  614. cell.innerText = optionsArray[ targetNode.text ];
  615. }
  616. }
  617. }
  618. cell.appendChild(input);
  619. //hack: somehow the checkboxes get unchecked after insertion into the cell so check 'em
  620. if (inputType=="checkbox")
  621. {
  622. if (input.value=="1" && !input.checked)
  623. input.checked = true;
  624. input.value = "1";
  625. }
  626. return showHideRow;
  627. }
  628. //-----------------------------------------------------------------------------
  629. //-----------------------------------------------------------------------------
  630. function createInputControlForNode(idPrefix, node, schemaNode, dataType, viewType, multiselect, columnHeader)
  631. {
  632. var id;
  633. var value;
  634. if (columnHeader)
  635. {
  636. id = multiselect ? multiselect.makeSetAllId(true) + '_0': null;
  637. value = null;
  638. }
  639. else
  640. {
  641. id = node.nodeName;
  642. value = node.text;
  643. if (value=="")
  644. value = getAttribute(schemaNode, 'default', '');
  645. }
  646. var type;
  647. var checked = false;
  648. var input;
  649. var inputName = 'input';
  650. var modifiedHandlerName = null;
  651. if ( viewType &&
  652. (viewType == "hidden" || viewType.indexOf("static")==0 || viewType == "tooltip"))
  653. {
  654. type = "hidden";
  655. if (columnHeader)
  656. {
  657. alert("Multiple selection is not supported for columns with controls of view type '" + viewType + "'!");
  658. return null;
  659. }
  660. }
  661. else if (viewType == 'select')
  662. {
  663. type = "select";
  664. inputName = 'select';
  665. modifiedHandlerName = 'onchange';
  666. }
  667. else if (viewType == 'showHideRowBtn')
  668. {
  669. if (columnHeader)
  670. {
  671. alert('Multiple selection is not supported for columns with toggle buttons!');
  672. return null;
  673. }
  674. id += '.btn';
  675. type = "button";
  676. value = "Show";
  677. }
  678. else if (dataType == "boolean")
  679. {
  680. type = "checkbox";
  681. modifiedHandlerName = 'onclick';
  682. if (value == "1" || value == "yes" || value=="true")
  683. checked = true;
  684. }
  685. else if (dataType == "file")
  686. {
  687. if (columnHeader)
  688. {
  689. alert('Multiple selection is not supported for columns with file controls!');
  690. return null;
  691. }
  692. type = "file";
  693. modifiedHandlerName = 'onclick';
  694. }
  695. else
  696. {
  697. type = "text";
  698. modifiedHandlerName = 'onchange';
  699. }
  700. input = document.createElement(inputName);
  701. if (inputName == 'input')
  702. input.type = type;
  703. if (columnHeader)
  704. {
  705. input.title = type=='checkbox' ? "Select or unselect all items" : "Update all items in this column with this value";
  706. input.id = id;
  707. }
  708. else
  709. {
  710. input.id = idPrefix ? (idPrefix + '.' + id) : id;
  711. input.name = input.id;
  712. input.value = value;
  713. }
  714. if (type == "checkbox")
  715. {
  716. if (checked)
  717. input.checked = true;
  718. }
  719. else if (type == 'text')
  720. {
  721. sz = getAttribute(schemaNode, 'size', null);
  722. if (sz)
  723. input.size = sz;
  724. }
  725. else if (viewType == 'select')
  726. {
  727. var source = getAttribute(schemaNode, 'source', null);
  728. if (source)
  729. {
  730. //we only support source == 'object' so far
  731. //optionTag defines tag name of child that defines an option
  732. var optionTag = getAttribute(schemaNode, 'option', 'option');
  733. /*
  734. '@text', '@value' and '@selected' attributes of schemaNode
  735. hold the needed tag names which are used to populate the drop down list
  736. these are supposed to be child nodes of option node in object hierarchy
  737. for instance, the following schema node definition creates a select object
  738. from the object node below and selects second item:
  739. <NameServices caption="Name Service" viewType="select" source="object"
  740. option="NameService" text="Name" value="Value" selected="Selected"/>
  741. object node:
  742. <NameServices>
  743. <NameService>
  744. <Name>ns1</Name>
  745. <Value>val1</Value>
  746. </NameService>
  747. <NameService>
  748. <Name>ns2</Name>
  749. <Value>val2</Value>
  750. <Selected>true</Selected>
  751. </NameService>
  752. </NameServices>
  753. */
  754. var textTag = getAttribute(schemaNode, 'text', null);
  755. var valueTag = getAttribute(schemaNode, 'value', null);
  756. var selectedTag = getAttribute(schemaNode, 'selected', null);
  757. if (node)
  758. {
  759. var options = node.selectNodes(optionTag);
  760. var n_options = options.length;
  761. for (var i=0; i<n_options; i++)
  762. {
  763. var option = document.createElement("option");
  764. option.text= options[i].selectSingleNode(textTag ).text;
  765. option.value=options[i].selectSingleNode(valueTag).text;
  766. input.add(option);
  767. var selected = options[i].selectSingleNode(selectedTag)
  768. if (selected && (selected.text=='1' || selected.text == 'true'))
  769. option.selected = true;
  770. }
  771. }
  772. else
  773. {
  774. var option = document.createElement("option");
  775. option.text= "-";
  776. option.value="";
  777. input.add(option);
  778. input.disabled = true;
  779. }
  780. }//source
  781. else
  782. {
  783. for ( var childSchemaNode = schemaNode.firstChild;
  784. childSchemaNode;
  785. childSchemaNode = childSchemaNode.nextSibling)
  786. {
  787. if (childSchemaNode.nodeName != '#comment' &&
  788. childSchemaNode.nodeName != 'Buttons')//ignore comments and buttons
  789. {
  790. if (childSchemaNode.nodeName == 'option')
  791. {
  792. var option = document.createElement("option");
  793. option.text=childSchemaNode.text;
  794. option.value=getAttribute(childSchemaNode, 'value', '');
  795. input.add(option);
  796. if (value && value == option.value)
  797. option.selected = true;
  798. }
  799. }
  800. }
  801. }//else
  802. }//viewType == 'select'
  803. if (modifiedHandlerName)
  804. setModifiedHandler(schemaNode, node, input, modifiedHandlerName, multiselect, columnHeader);
  805. if ( getAttributeBool(schemaNode, 'disabled', false) || (node && getAttributeBool(node, 'disabled', false)) )
  806. input.disabled = true;
  807. return input;
  808. }
  809. function getAttribute(obj, attrName, defaultVal)
  810. {
  811. var attr = obj.attributes.getNamedItem(attrName);
  812. return attr ? attr.nodeValue : defaultVal;
  813. }
  814. function getAttributeBool(obj, attrName, defaultVal)
  815. {
  816. var attr = obj.attributes.getNamedItem(attrName);
  817. return attr ? (attr.nodeValue=='true' || attr.nodeValue == '1') : defaultVal;
  818. }
  819. //handle button with a given name
  820. //
  821. function enableButton(btnName, enable)
  822. {
  823. //note that there may be 2 buttons (at top and bottom of table) with the same name
  824. //
  825. var btns = document.getElementsByName(btnName);
  826. var nBtns= btns.length;
  827. for (var j=0; j < nBtns; j++)
  828. btns[j].disabled = !enable;
  829. }
  830. //handle button with a given prefix + enumeration (i.e. prefix1, prefix2, prefix3...)
  831. //
  832. function enableButtons(btnNamePrefix, enable)
  833. {
  834. for (var i=1; ; i++)
  835. {
  836. //note that there may be 2 buttons (at top and bottom of table) with the same name
  837. //
  838. var btns = document.getElementsByName(btnNamePrefix + i);
  839. var nBtns= btns.length;
  840. if (nBtns > 0)
  841. {
  842. for (var j=0; j < nBtns; j++)
  843. btns[j].disabled = !enable;
  844. }
  845. else
  846. break;
  847. }
  848. }
  849. function onAdd(nodeSetName)
  850. {
  851. //if (!addImmediateChildrenFromHtmlObjects(schemaRootNode, objRootNode, xmlDoc))
  852. // return;
  853. updateNestedData("add", nodeSetName, -1);
  854. ms_reinitializeAll();
  855. setModified();
  856. }
  857. function onEdit(nodeSetName)
  858. {
  859. var index = getFirstCheckedItemIndex(nodeSetName);
  860. updateNestedData("edit", nodeSetName, index);
  861. setModified();
  862. }
  863. function onDelete(nodeSetName, simulate)
  864. {
  865. var multiselect = ms_lookupByTableAndColumn(nodeSetName, 0);
  866. var index = getFirstCheckedItemIndex(nodeSetName);
  867. var rc = false;
  868. if (index == -1)
  869. alert("Please select one or more items to delete!");
  870. else
  871. if (confirm('Are you sure you want to ' + (simulate ? 'remove' : 'delete') + ' the selected item' +
  872. (multiselect.getSelectionCount()!=1?'s':'') + '?'))
  873. {
  874. rc = true;
  875. while (rc && index != -1)
  876. {
  877. if (!updateNestedData("delete", nodeSetName, index, simulate))
  878. rc = false;
  879. else
  880. index = getFirstCheckedItemIndex(nodeSetName, simulate ? index+1 : index);
  881. }
  882. if (!simulate)
  883. ms_reinitializeAll();
  884. onRowCheck(multiselect.id);
  885. setModified();
  886. }
  887. return rc;
  888. }
  889. function getFirstCheckedItemIndex(xpath, startIndex)
  890. {
  891. var ndx = -1;
  892. var checkBoxes = document.getElementsByName(xpath+".checkbox");
  893. if (startIndex == undefined)
  894. startIndex = 0;
  895. //if we have only one checkbox then length is undefined in that case
  896. if (checkBoxes.length == undefined)
  897. {
  898. //we (un)checked the same checkbox so toggle selection
  899. if (checkBoxes.checked && startIndex == 0)
  900. ndx = 0;
  901. }
  902. else
  903. {
  904. var nCheckBoxes = checkBoxes.length;
  905. for (var i=startIndex; i<nCheckBoxes; i++)
  906. if (checkBoxes[i].checked)
  907. {
  908. ndx = i;
  909. break;
  910. }
  911. }
  912. return ndx;
  913. }
  914. function getEnclosingTableRow(htmlObj)
  915. {
  916. var row = null;
  917. for (var parent = htmlObj.parentElement; parent; parent = parent.parentElement)
  918. if (parent.tagName.toUpperCase() == 'TR' && parent.id != '')
  919. {
  920. row = parent;
  921. break;
  922. }
  923. return row;
  924. }
  925. function addImmediateChildrenFromHtmlObjects(doc, schemaNode, objNode, xmlDoc)
  926. {
  927. //keep xmlDoc in sync with contents of this page
  928. //so create elements corresponding to all immediate input fields
  929. for ( var childSchemaNode = schemaNode.firstChild;
  930. childSchemaNode != null;
  931. childSchemaNode = childSchemaNode.nextSibling)
  932. {
  933. var name = childSchemaNode.nodeName;
  934. if (name == "#comment" || name == 'Buttons')//ignore comments and buttons
  935. continue;
  936. if (childSchemaNode.hasChildNodes())
  937. {
  938. //if this node has children but only occurs once then create a node
  939. //corresponding to this schema node and process its children instead
  940. //
  941. var maxOccurs = getAttribute(childSchemaNode, 'maxOccurs', null);
  942. if (maxOccurs == "1")
  943. {
  944. var newNode = objNode.selectSingleNode(name);
  945. if (!newNode)
  946. {
  947. newNode = xmlDoc.createElement(name);
  948. objNode.appendChild(newNode);
  949. }
  950. addImmediateChildrenFromHtmlObjects(doc, childSchemaNode, newNode, xmlDoc);
  951. }
  952. }
  953. else
  954. {
  955. //only process nodes which don't have children since those would be processed
  956. //by add/delete/edit button handlers
  957. //we may have already added this node if we had errored out
  958. //in last try. So only add if it does not exist.
  959. //
  960. var newNode = objNode.selectSingleNode(name);
  961. if (!newNode)
  962. {
  963. newNode = xmlDoc.createElement(name);
  964. objNode.appendChild(newNode);
  965. }
  966. var htmlObj = doc.getElementById(name);
  967. if (htmlObj != undefined) //html objects may be spread across multiple pages in a wizard
  968. {
  969. if (htmlObj.type == "checkbox")
  970. newNode.text = htmlObj.checked ? "1" : "0";
  971. else
  972. newNode.text = htmlObj.value;
  973. }
  974. }
  975. }
  976. return true;
  977. }
  978. function replaceImmediateChildrenFromHtmlObjects(objNode, schemaNode)
  979. {
  980. for ( var childNode = objNode.firstChild;
  981. childNode != null;
  982. childNode = childNode.nextSibling)
  983. {
  984. var name = childNode.nodeName;
  985. if (childNode.selectSingleNode('*') == null)
  986. {
  987. var htmlObj = document.getElementById(name);
  988. var schemaChildNode = schemaNode.selectSingleNode(name);
  989. var dataType = getAttribute(schemaChildNode, 'dataType', null);
  990. if (dataType)
  991. {
  992. if (dataType == 'boolean')
  993. childNode.text = htmlObj.checked ? '1' : '0';
  994. else
  995. childNode.text = htmlObj.value;
  996. }
  997. else
  998. childNode.text = htmlObj.value;
  999. }
  1000. }
  1001. }
  1002. /*unused so far...
  1003. function createUnescapedUrl(doc, schemaNode, objNode, xmlDoc, prefix)
  1004. {
  1005. //create a url with elements in schema and object nodes
  1006. //
  1007. var url;
  1008. for ( var childSchemaNode = schemaNode.firstChild;
  1009. childSchemaNode != null;
  1010. childSchemaNode = childSchemaNode.nextSibling)
  1011. {
  1012. var name = childSchemaNode.nodeName;
  1013. if (name == "#comment" || name == 'Buttons')//ignore comments and buttons
  1014. continue;
  1015. if (childSchemaNode.hasChildNodes())
  1016. {
  1017. //if this node has children but only occurs once then create a node
  1018. //corresponding to this schema node and process its children instead
  1019. //
  1020. var maxOccurs = getAttribute(schemaChildNode, 'maxOccurs', null);
  1021. if (maxOccurs == "1")
  1022. {
  1023. var childNode = objNode.selectSingleNode(name);
  1024. if (childNode)
  1025. url += createUnescapedUrl(doc, childSchemaNode, childNode, xmlDoc, name);
  1026. }
  1027. }
  1028. else
  1029. {
  1030. //only process nodes which don't have children since those would be processed
  1031. //by add/delete/edit button handlers
  1032. //we may have already added this node if we had errored out
  1033. //in last try. So only add if it does not exist.
  1034. //
  1035. var childNode = objNode.selectSingleNode(name);
  1036. if (childNode)
  1037. {
  1038. url += '&';
  1039. if (prefix)
  1040. url += prefix + '.';
  1041. url += name + '=' + childNode.text;
  1042. }
  1043. }
  1044. }
  1045. return url;
  1046. }
  1047. */
  1048. function isNumber(str)
  1049. {
  1050. return parseInt(str).toString()==str;
  1051. }
  1052. function updateNestedData(operation, strXPath, index, simulateDelete)
  1053. {
  1054. var tableObj = document.all[strXPath];
  1055. var rc = true;
  1056. //Get a pointer to the specific note to pass to the modal dialog.
  1057. var targetNode;
  1058. if (operation == "add" || operation == "edit")
  1059. {
  1060. //parse the strXPath (which is of the form A.B.2.C) to an actual xpath
  1061. //(like A/B[2]/C) so we can use it to find the corresponding data node
  1062. //as well as the schema node.
  1063. //Note that the first token (i.e. A) cannot have any index since it is the
  1064. //argument node (root) so we parse from second token.
  1065. //
  1066. var tokens = new Array();
  1067. tokens = strXPath.split('.');
  1068. var nTokens = tokens.length;
  1069. if (index == -1)//index not specified (for appending row) so add after last row
  1070. {
  1071. var checkBoxes = document.getElementsByName(strXPath+".checkbox");
  1072. index = checkBoxes.length;
  1073. tokens[nTokens++] = index;
  1074. }
  1075. var childSchemaNode = schemaRootNode;
  1076. var parentNode = objRootNode.selectSingleNode(tokens[0]);
  1077. for (var i=1; i<nTokens; i++)
  1078. {
  1079. targetNode = parentNode;
  1080. var xpath = tokens[i];
  1081. var nextI;
  1082. if (i+1<nTokens && isNumber(tokens[i+1]))
  1083. {
  1084. xpath += '[' + tokens[i+1] + ']';
  1085. nextI = i+1;//we have already processed next token
  1086. }
  1087. else
  1088. nextI = i;
  1089. childSchemaNode = childSchemaNode.selectSingleNode(tokens[i]);
  1090. targetNode = parentNode.selectSingleNode(xpath);
  1091. i = nextI;
  1092. }
  1093. if (operation == 'add')
  1094. {
  1095. //create a new node to add
  1096. var newNode = xmlDoc.createElement(tokens[nTokens-2]); //pick second last to get name
  1097. //we would like to insert this new node at the specified position so if there is
  1098. //already a sibling then specify that sibling node to insert before that node so
  1099. //the new node pushes it down and gets inserted before it
  1100. //
  1101. targetNode = parentNode.insertBefore(newNode, targetNode);
  1102. }
  1103. else //edit
  1104. if ( targetNode == null)
  1105. {
  1106. alert('No matching data to edit!');
  1107. return false;
  1108. }
  1109. var nodeName = targetNode.nodeName;
  1110. var addMethod = getAttribute(childSchemaNode, "addMethod", null);
  1111. if (addMethod)
  1112. {
  1113. /* if addMethod is defined as customMethod(), define a Function onAddHandler as follows:
  1114. function onAddHandler(operation, xmlDoc, targetNode, component, command, xpath, schemaNode)
  1115. {
  1116. return customMethod(operation, xmlDoc, targetNode, component, command, xpath, schemaNode);
  1117. }
  1118. */
  1119. var onAddHandler = new Function(
  1120. "operation", "xmlDoc", "targetNode", "component", "command", "xpath", "schemaNode",
  1121. "return " + addMethod+"(operation, xmlDoc, targetNode, component, command, xpath, schemaNode)");
  1122. rc = onAddHandler(operation, xmlDoc, targetNode, component, command, strXPath, schemaRootNode);
  1123. if (!rc)
  1124. {
  1125. newNode = null;
  1126. return rc;
  1127. }
  1128. }
  1129. var bRowCheckbox = getAttributeBool(childSchemaNode, 'checkboxes', true);
  1130. var bChecked;
  1131. var row_num;
  1132. if (operation == "add")
  1133. {
  1134. var rows = tableObj.rows;
  1135. row_num = rows.length;//row 0 is header
  1136. //if this is the first row getting into the table then replace the "- none -" row
  1137. //
  1138. if (row_num == 2 && rows[1].cells[0].innerText == '- none -')
  1139. {
  1140. tableObj.deleteRow(1);
  1141. row_num = 1;
  1142. }
  1143. bChecked = false;
  1144. }
  1145. else
  1146. {
  1147. //edit
  1148. row_num = index+1;//row 0 is header
  1149. deleteRowFromTable(tableObj, row_num, strXPath, false); //row 0 is header
  1150. bChecked = true;
  1151. }
  1152. bChecked = getAttributeBool(childSchemaNode, 'checked', bChecked);
  1153. var row = tableObj.insertRow(row_num);//insert after row index row_num
  1154. var lastRowIndex = tableObj.lastRowIndex ? parseInt(tableObj.lastRowIndex) + 1 : 0;
  1155. updateItemList(tableObj, lastRowIndex, null);
  1156. var showHideRow = populateTableRow(tableObj, row, targetNode, childSchemaNode, strXPath, bRowCheckbox, bChecked);
  1157. }
  1158. else//delete
  1159. {
  1160. if (simulateDelete)
  1161. rc = deleteRowFromTable(tableObj, index, strXPath, true);
  1162. else
  1163. {
  1164. if (objRootNode)
  1165. {
  1166. var objNodes = objRootNode.selectNodes(strXPath.replace('.', '/'));
  1167. targetNode = objNodes.item(index);
  1168. if (targetNode == null)
  1169. {
  1170. alert('No matching data available!');
  1171. return false;
  1172. }
  1173. }
  1174. else
  1175. targetNode = null;
  1176. rc = deleteRowFromTable(tableObj, index, strXPath, false);
  1177. if (rc && targetNode)
  1178. targetNode.parentNode.removeChild(targetNode);
  1179. }
  1180. }
  1181. return rc;
  1182. }
  1183. function deleteRowFromTable(tableObj, node_index, xpath, simulate)
  1184. {
  1185. var checkBoxes = document.getElementsByName(xpath+".checkbox");
  1186. var cb = checkBoxes[node_index];
  1187. var row = getEnclosingTableRow(cb);
  1188. if (row == null)
  1189. {
  1190. alert("Failed to find a row corresponding to item '" + xpath + '[' + nodex_index + "]'");
  1191. return false;
  1192. }
  1193. var rowId = row.id;
  1194. var rowIndex = row.rowIndex;
  1195. var pos = rowId.lastIndexOf('.');
  1196. if (!updateItemList(tableObj, null, rowId.substring(pos+1)))
  1197. return false;
  1198. if (!simulate)
  1199. {
  1200. tableObj.deleteRow(rowIndex);
  1201. //see if there is a corresponding showHideRow (toggle row) and delete it, if present
  1202. //
  1203. var toggle_rows = document.getElementsByName(rowId + '.toggle');
  1204. var n_toggle_rows = toggle_rows.length;
  1205. for (i=0; i<n_toggle_rows; i++)
  1206. tableObj.deleteRow(toggle_row[i].rowIndex);
  1207. }
  1208. return true;
  1209. }
  1210. //define a stub that may be overridden by a component's command
  1211. //if special handling of item selection is desired
  1212. //
  1213. function onRowCheckHandler(multiSelectObj)
  1214. {
  1215. }
  1216. function onRowCheck(multiselect_id)
  1217. {
  1218. //the user checked on select all button one so we have at least one checkbox
  1219. //
  1220. //enable delete and edit buttons
  1221. //
  1222. var multiselect = ms_lookup(multiselect_id);
  1223. var tableId = multiselect.o_table.id;
  1224. var nSelected = multiselect.getSelectionCount();
  1225. var anySelected = nSelected > 0;
  1226. enableButton(tableId + ".Delete", anySelected);
  1227. enableButtons(tableId + ".Edit", nSelected==1);
  1228. if (!multiselect.b_singleSelect)
  1229. enableButtons(tableId + ".MultiEdit", anySelected);
  1230. onRowCheckHandler(multiselect);
  1231. }
  1232. function onColumnCheck(newValue, multiselect_id)
  1233. {
  1234. //the user checked on select all button one so we have at least one checkbox
  1235. //
  1236. //var multiselect = ms_lookup(multiselect_id);
  1237. //var tableId = multiselect.o_table.id;
  1238. }
  1239. function onShowHideRow(tableId, rowId, srcObj, content)
  1240. {
  1241. var table = document.getElementById(tableId);
  1242. var prevTableHt = table.offsetHeight;
  1243. var srcObjId = srcObj.id;
  1244. var toggleRowId = srcObjId + '.toggle';
  1245. var toggleRow = document.getElementById(toggleRowId);
  1246. var bShow;
  1247. var srcCell = srcObj.parentElement;
  1248. var btnRow = document.getElementById(rowId);;
  1249. //find out if btnRow has a checkbox in cell 0
  1250. //
  1251. var nRowCheckbox = 0;
  1252. var firstBtnRowCell = btnRow.cells[0];
  1253. var inputs = firstBtnRowCell.getElementsByTagName('INPUT');
  1254. var nInputs = inputs.length;
  1255. for (var i=0; i<nInputs; i++)
  1256. {
  1257. var input = inputs[i];
  1258. if (input.type == 'checkbox' && input.name.lastIndexOf('.checkbox'))
  1259. {
  1260. nRowCheckbox = 1;
  1261. break;
  1262. }
  1263. }
  1264. var toggleRowHt;
  1265. if (!toggleRow)
  1266. {
  1267. var enclosingRow = document.getElementById(rowId);
  1268. toggleRow = table.insertRow(enclosingRow.rowIndex+1);
  1269. toggleRow.id = toggleRowId;
  1270. toggleRow.name = rowId + '.toggle';
  1271. var cell = toggleRow.insertCell(-1);
  1272. cell.colSpan = btnRow.cells.length - nRowCheckbox;
  1273. cell.style.textAlign = 'left';
  1274. if (!content)
  1275. {
  1276. var pos = srcObjId.lastIndexOf('.');
  1277. var hiddenInputId = srcObjId.substring(0, pos);
  1278. var hiddenInput = srcCell.all[ hiddenInputId ];
  1279. content = '<pre>'+ hiddenInput.value + '</pre>';
  1280. }
  1281. cell.innerHTML = content;
  1282. toggleRowHt = toggleRow.offsetHeight;
  1283. bShow = true;
  1284. }
  1285. else
  1286. {
  1287. bShow = toggleRow.style.display == 'none';
  1288. if (bShow)
  1289. {
  1290. toggleRow.style.display = 'block';
  1291. toggleRowHt = toggleRow.offsetHeight;
  1292. }
  1293. else
  1294. {
  1295. toggleRowHt = toggleRow.offsetHeight;
  1296. toggleRow.style.display = 'none';
  1297. }
  1298. }
  1299. if (srcObj.type == 'button')
  1300. {
  1301. var pattern = bShow ? 'Show' : 'Hide';
  1302. var replace = bShow ? 'Hide' : 'Show';
  1303. srcObj.value = srcObj.value.replace( new RegExp(pattern), replace);
  1304. }
  1305. if (nRowCheckbox)
  1306. {
  1307. /*BUG in IE: document.getElementsByName(rowId + '.toggle') does not return any rows
  1308. even though we may have just added one so use alternate implementation by
  1309. enumerating rows (slower)*/
  1310. var toggleRowName = rowId + '.toggle';
  1311. var rowSpan = 1;
  1312. var toggle_rows = table.getElementsByTagName('TR');
  1313. var n_toggle_rows = toggle_rows.length;
  1314. for (i=0; i<n_toggle_rows; i++)
  1315. {
  1316. var name = toggle_rows[i].name;
  1317. if (name==toggleRowName && toggle_rows[i].style.display != 'none')
  1318. rowSpan++;
  1319. }
  1320. firstBtnRowCell.rowSpan = rowSpan;
  1321. firstBtnRowCell.vAlign = rowSpan>1 ? 'top' : 'center';
  1322. }
  1323. var bDiv = document.getElementById( 'DB.' + tableId );
  1324. if (bDiv)
  1325. {
  1326. var divHt = bDiv.offsetHeight;
  1327. bDiv.style.height = bShow ? (divHt + toggleRowHt+1) : divHt;
  1328. }
  1329. var resizeHandler = document.body.onresize;
  1330. if (resizeHandler)
  1331. resizeHandler();
  1332. }
  1333. /* this function takes a string of the form "prefix{xpath}suffix" and
  1334. returns prefixXYZsuffix, where XYZ is the result of execution of selectSingleNode(xpath).
  1335. Multiple {xpath} blocks may be embedded within the string. This is primarily intended to
  1336. substitute parameter values before form submission with resulting action.
  1337. */
  1338. function expand_embedded_xpaths(str, schemaNode, node, bEscape)
  1339. {
  1340. var open_brace = str.indexOf('{');
  1341. if (open_brace == -1)
  1342. return str;
  1343. var close_brace = str.indexOf('}', open_brace+1);
  1344. if (close_brace == -1)
  1345. close_brace = str.length+1;
  1346. var embraced = str.substring(open_brace+1, close_brace);
  1347. var result;
  1348. if (embraced.length)
  1349. {
  1350. if (embraced == '.')
  1351. result = node.text;
  1352. else
  1353. {
  1354. var targetNode = node.selectSingleNode(embraced);
  1355. result = targetNode ? targetNode.text : embraced;
  1356. }
  1357. }
  1358. else
  1359. result = '';
  1360. return str.substring(0, open_brace) +
  1361. (bEscape != false ? escape(result) : result) +
  1362. expand_embedded_xpaths( str.substring(close_brace+1), schemaNode, node, bEscape );
  1363. }
  1364. function updateItemList(tableObj, addItem, delItem, newValue)
  1365. {
  1366. var id = tableObj.id;
  1367. id += ".itemlist";
  1368. var itemListInput = document.getElementById(id);
  1369. if (itemListInput == null)
  1370. {
  1371. /* As per DHTML references in MSDN:
  1372. The NAME attribute cannot be set at run time on elements dynamically
  1373. created with the createElement method. To create an element with a
  1374. name attribute, include the attribute and value when using the createElement method.
  1375. */
  1376. itemListInput = document.createElement("<INPUT TYPE='hidden' NAME='"+id+"'></INPUT>");
  1377. itemListInput.id = id;
  1378. itemListInput.value = "+";
  1379. document.forms[0].appendChild( itemListInput );
  1380. }
  1381. if (addItem != null)
  1382. itemListInput.value += addItem + '+';
  1383. else
  1384. if (delItem != null)
  1385. {
  1386. var list = itemListInput.value;
  1387. var pattern = '+' + delItem + '+';
  1388. var begin = list.indexOf(pattern);
  1389. if (begin == -1)
  1390. {
  1391. alert("Table row management error!");
  1392. debugger;
  1393. return false;
  1394. }
  1395. var end = begin + pattern.length -1;
  1396. itemListInput.value = list.substring(0, begin) + list.substring(end);
  1397. }
  1398. else
  1399. itemListInput.value = newValue;
  1400. return true;
  1401. }
  1402. function setItemListFromSelectedRowsOnly(tableId)
  1403. {
  1404. var checkBoxes = document.getElementsByName(tableId+".checkbox");
  1405. var nCheckBoxes = checkBoxes.length;
  1406. var itemList='+';
  1407. for (var i=0; i<nCheckBoxes; i++)
  1408. {
  1409. var cb = checkBoxes[i];
  1410. if (cb.checked)
  1411. {
  1412. var rowId = getEnclosingTableRow(cb).id;
  1413. var lastDot = rowId.lastIndexOf('.');
  1414. var index = rowId.substring(lastDot+1);
  1415. itemList += index + '+';
  1416. }
  1417. }
  1418. var tableObj = document.getElementById( tableId );
  1419. updateItemList(tableObj, null, null, itemList);
  1420. }
  1421. function serializeTableRows(xpath, tableId, checkedRowsOnly)
  1422. {
  1423. //xpath can be delimited by / or .
  1424. //
  1425. if (!tableId)
  1426. tableId = xpath;
  1427. tableId = tableId.replace( /\//g, '.');//replace any / in xpath by .
  1428. var xpath_slashes = xpath.replace( /\./g, '/');//replace any . in xpath by /
  1429. var checkBoxes = document.getElementsByName(tableId+".checkbox");
  1430. var nCheckBoxes = checkBoxes.length;
  1431. var xml=new Array();
  1432. var j = 0;
  1433. //if xpath_slashes is of the form A/B/C, add <A><B> as prefix
  1434. //
  1435. var s_array = xpath_slashes.split('/');
  1436. for (var i = 0; i< s_array.length-1; i++)
  1437. {
  1438. xml[j++] = '<';
  1439. xml[j++] = s_array[i];
  1440. xml[j++] = '>';
  1441. }
  1442. for (var i=0; i<nCheckBoxes; i++)
  1443. {
  1444. var cb = checkBoxes[i];
  1445. if (!checkedRowsOnly || cb.checked)
  1446. {
  1447. var objXpath = xpath_slashes + '[' + i + ']';
  1448. var obj = objRootNode.selectSingleNode(objXpath);
  1449. xml[j++] = obj.xml;
  1450. }
  1451. }
  1452. //if xpath_dots is of the form A.B.C, add </B></A> as suffix
  1453. //
  1454. for (var i = s_array.length-2; i>=0 ; i--)
  1455. {
  1456. xml[j++] = '</';
  1457. xml[j++] = s_array[i];
  1458. xml[j++] = '>';
  1459. }
  1460. return xml.join('');
  1461. }
  1462. function findMaxTableColumns(tableObj)
  1463. {
  1464. var nColsMax = 0;
  1465. var rows = tableObj.rows;
  1466. var nRows = rows.length;
  1467. for (var i=0; i<nRows; i++)
  1468. {
  1469. var nCols = rows[i].cells.length;
  1470. if (nCols > nColsMax)
  1471. nColsMax = nCols;
  1472. }
  1473. return nColsMax;
  1474. }
  1475. // this is a place holder to be redefined by the component's command
  1476. // if special handling is needed upond modified state change
  1477. //
  1478. function onDocumentModified(modified)
  1479. {
  1480. }
  1481. function setModified(val)
  1482. {
  1483. if (document.modified != val)
  1484. {
  1485. document.modified = val != undefined ? val : true;
  1486. onDocumentModified(val);
  1487. }
  1488. }
  1489. function setModifiedHandler(schemaNode, node, htmlObj, handlerName, multiselect, columnHeader)
  1490. {
  1491. var handlerAttrib = getAttribute(schemaNode, handlerName, null);
  1492. var handlerScript = new Array();
  1493. var i = 0;
  1494. handlerScript[i++] = 'setModified(); ';
  1495. if (multiselect)
  1496. {
  1497. handlerScript[i++] = columnHeader ? 'ms_setAll' : 'ms_onChange';
  1498. handlerScript[i++] = "(this, '";
  1499. handlerScript[i++] = multiselect.tableId;
  1500. handlerScript[i++] = "',";
  1501. handlerScript[i++] = multiselect.n_column;
  1502. handlerScript[i++] = '); ';
  1503. if (multiselect.n_column > 0 && columnHeader)
  1504. handlerScript[i++] = "this.style.display = 'none'";
  1505. }
  1506. if (handlerAttrib && node)
  1507. handlerScript[i++] = expand_embedded_xpaths( handlerAttrib, schemaNode, node);
  1508. if (handlerName == 'onclick')
  1509. htmlObj.onclick = new Function(handlerScript.join(''));
  1510. else
  1511. if (handlerName == 'onchange')
  1512. htmlObj.onchange = new Function(handlerScript.join(''));
  1513. }
  1514. function onBeforeUnloadDocument()
  1515. {
  1516. //null; //don't let IE display any dialog box...any string value returned makes IE do so
  1517. //window.event.cancelBubble = document.modified && !confirm('Are you sure you want to lose changes to this web page?');
  1518. if (document.modified)
  1519. event.returnValue = 'All changes will be lost!';
  1520. }
  1521. function disableSubmitButtons(disable)
  1522. {
  1523. if (typeof disable == 'undefined')
  1524. disable = true;
  1525. //enable/disable all submit buttons:
  1526. var inputs = document.getElementsByTagName('INPUT');
  1527. var nInputs = inputs.length;
  1528. for (var i=0; i<nInputs; i++)
  1529. if (inputs[i].type.toUpperCase() == 'SUBMIT')
  1530. inputs[i].disabled = disable;
  1531. }
  1532. function onSubmit()
  1533. {
  1534. /*
  1535. if (bAdd)
  1536. {
  1537. //add immediate children to our data island. Note that nested data is updated
  1538. //as a result of add/delete handlers
  1539. //
  1540. if (!addImmediateChildrenFromHtmlObjects(schemaRootNode, objRootNode, xmlDoc))
  1541. return false;
  1542. }
  1543. else
  1544. replaceImmediateChildrenFromHtmlObjects(objRootNode. schemaRootNode);
  1545. //update the value of our hidden HTML control that gets sent back with the submission
  1546. //
  1547. document.getElementById('xmlArgs').value = xmlDoc.xml;
  1548. alert(xmlDoc.xml);
  1549. */
  1550. setModified(false); //so we don't warn about losing changes
  1551. disableSubmitButtons();
  1552. return true;
  1553. }
  1554. function submitForm(action)
  1555. {
  1556. setModified(false); //so we don't warn about losing changes
  1557. var form = document.forms[0];
  1558. form.action = action;
  1559. var bModified = document.modified;
  1560. if (onSubmit())
  1561. {
  1562. try {
  1563. form.submit();
  1564. } catch (e) {
  1565. alert('Form submission failed: ' + e.description);
  1566. if (bModified)
  1567. setModified(true);
  1568. disableSubmitButtons(false);
  1569. }
  1570. }
  1571. return false;
  1572. }
  1573. function submitSelectedItem(xpath, action, tableId)
  1574. {
  1575. //xpath can be delimited by / or .
  1576. //
  1577. if (!tableId)
  1578. tableId = xpath;
  1579. tableId = tableId.replace( /\//g, '.');//replace any / in xpath by .
  1580. var xpath_slashes = xpath.replace( /\./g, '/');//replace any . in xpath by /
  1581. var n_selected_row = getFirstCheckedItemIndex(tableId);
  1582. var objNodes = objRootNode.selectNodes(xpath_slashes);
  1583. node = objNodes.item(n_selected_row);
  1584. if (node == null)
  1585. alert('No matching data!');
  1586. else
  1587. {
  1588. var expanded = expand_embedded_xpaths(action, schemaRootNode, node);
  1589. submitForm(expanded);
  1590. }
  1591. return false;
  1592. }
  1593. function submitSelectedItems(xpath, action)
  1594. {
  1595. //xpath can be delimited by / or .
  1596. //
  1597. var tableId = xpath.replace( /\//g, '.');//replace any / in xpath by .
  1598. setItemListFromSelectedRowsOnly(tableId);
  1599. return submitForm(action);
  1600. }
  1601. function submitSelectedItemsAsXml(xpath, action, input_name, tableId)
  1602. {
  1603. var XmlArg = serializeTableRows(xpath, tableId, true);
  1604. var inputs = document.getElementsByName( input_name );
  1605. if (inputs.length==0)
  1606. {
  1607. input = document.createElement('input');
  1608. input.type = 'hidden';
  1609. input.value = XmlArg;
  1610. input.name = input_name;
  1611. document.forms[0].appendChild( input );
  1612. }
  1613. else
  1614. inputs[0].value = XmlArg;
  1615. return submitForm(action);
  1616. }