ui_engine.js 59 KB

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