/*############################################################################## # Copyright (C) 2011 HPCC Systems. # # All rights reserved. This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . ############################################################################## */ var command; var component; var xmlDoc; var schemaRootNode; var objRootNode; var bAdd; var argsNodeName; function loadCommandInfo() { setModified(false); document.body.onbeforeunload = onBeforeUnloadDocument; component = document.getElementById('component').value; command = document.getElementById('command').value; if (typeof xmlSchema != 'undefined' && xmlSchema.documentElement) { var xpath = '/Components/' + component + '/Commands/' + command; var commandSchemaNode = xmlSchema.documentElement.selectSingleNode(xpath); argsNodeName = getAttribute(commandSchemaNode, 'argsNode', 'Arguments'); schemaRootNode = commandSchemaNode.selectSingleNode(argsNodeName); if (schemaRootNode == null) { alert('No arguments node found in XML schema!'); return; } } else { schemaRootNode = null; argsNodeName = 'Arguments'; } var prevArgsDoc = document.getElementById("xmlPrevArgsDoc"); if (prevArgsDoc) { xmlDoc = prevArgsDoc; objRootNode = prevArgsDoc.documentElement; if (schemaRootNode) { var captionObj = document.getElementById('pageCaption'); if (captionObj) captionObj.innerText = expand_embedded_xpaths( captionObj.innerText, schemaRootNode, objRootNode, false); } } else objRootNode = null; var subCaptionObj = document.getElementById('pageSubCaption'); if (subCaptionObj) { var subcaption = subCaptionObj.innerHTML; if (subcaption.indexOf('Loading,')==0) subCaptionObj.style.display = 'none'; else if (prevArgsDoc && schemaRootNode) subCaptionObj.innerText = expand_embedded_xpaths( subcaption, schemaRootNode, objRootNode, false); } //alert(tableObj.outerHTML); //alert(document.forms[0].outerHTML); initFixedTables(); ms_initializeAll(); var pageBody = document.getElementById('pageBody'); if (pageBody) pageBody.focus(); if (typeof onLoadCustom != 'undefined') onLoadCustom(); } function createTable(id, className, border, width) { tableObj = document.createElement('table'); tableObj.id = id; if (border) tableObj.border = border; if (className) tableObj.className='sort-table'; if (width) tableObj.width = width; return tableObj; } function populateTable(tableObj, targetNode, schemaNode, xpath) { //make header createColumnHeaders(tableObj, null, targetNode, schemaNode, xpath, undefined); addTableRows(tableObj, targetNode, schemaNode, xpath, null); //create buttons var xpathBtns = (schemaNode == schemaRootNode && argsNodeName == '.') ? 'Buttons' : '../Buttons'; var btnsNode = schemaNode.selectSingleNode(xpathBtns); if (btnsNode || schemaNode == schemaRootNode) { createButtons(tableObj, btnsNode, false); if (tableObj.offsetHeight > 600) createButtons(tableObj, btnsNode, true); } } function createColumnHeaders(tableObj, row, targetNode, schemaNode, xpath, nTableRows) { //insert checkbox column header unless checkboxes are not desired // var xpath2; if (schemaNode == schemaRootNode) xpath2 = null; else xpath2 = xpath ? xpath + '.' + schemaNode.nodeName : schemaNode.nodeName; var maxOccurs = getAttribute(schemaNode, 'maxOccurs', null); if (maxOccurs)//each table column is an attribute of a target node { if (maxOccurs == 'unbounded') { var checkboxes = getAttributeBool(schemaNode, 'checkboxes', true); if (checkboxes) { if (!row) row = tableObj.insertRow(); col = document.createElement('th'); col.width = '10'; row.appendChild(col); //make multi selection checkbox if multiple selection is desired // var multiselect = getAttributeBool(schemaNode, 'multiselect', false); if (multiselect) { var childObjNodes = targetNode.selectNodes(schemaNode.nodeName); nTableRows = childObjNodes.length; var multiselect = ms_create( tableObj.id, onRowCheck ) if (nTableRows > 1) { //insert checkbox var bChecked = getAttributeBool(schemaNode, 'checked', false); //var cbName = xpath2 + ".checkbox"; var s = new Array(); var i=0; s[i++] = ' 1) && getAttributeBool(childSchemaNode, 'multiselect', false)) { //if there are multiple rows in this table //create a multiple selection object to manage this column // var multiselect = ms_create( tableObj.id, onColumnCheck, null, row.cells.length ) thObj.id = multiselect.makeSetAllId(true); var dataNode = childObjNode ? childObjNode.selectNodes(childSchemaNode.nodeName)[0] : null; var dataType = getAttribute(childSchemaNode, 'dataType', null); var input = createInputControlForNode(xpath, dataNode, childSchemaNode, dataType, viewType, multiselect, true); input.style.display = 'none'; multiselect.inputTag = input.tagName; multiselect.inputType = input.type; var s = new Array(); var i = 0; s[i++] = "'; else innerHTML += ''; } cell.innerHTML = innerHTML; } function addTableRows(tableObj, objNode, schemaNode, xpath, lastRow) { var name = schemaNode.nodeName; if (name == "#comment" || name == 'Buttons')//ignore comments return; var maxOccurs = getAttribute(schemaNode, 'maxOccurs', null); var xpath2; if (xpath) xpath2 = xpath + '.' + name; else xpath2 = (schemaNode == schemaRootNode && argsNodeName=='Arguments') ? null : name; var showHideRow = null; if (maxOccurs == "unbounded") { if (tableObj.id != xpath2) { //create another table that would occupy entire cell of parent table's row var childTableObj = createTable(xpath2, 'sort-table', 1, '100%'); var row = tableObj.insertRow(-1);//insert new row var cell = row.insertCell(); cell.appendChild(childTableObj); populateTable(childTableObj, objNode, schemaNode, xpath); } else { var bRowCheckbox = getAttributeBool(schemaNode, 'checkboxes', true); var checked = getAttributeBool(schemaNode, 'checked', false); //append rows in table var targetNodes = objNode.selectNodes(name); var nNodes = targetNodes.length; for (var i=0; i'); cell.innerText = showHideRow['node'].text; }//if }//for } } else if (maxOccurs == "1" || schemaNode == schemaRootNode) { var targetNode = objNode.selectSingleNode(name); if (!targetNode) { targetNode = xmlDoc.createElement(name); objNode.appendChild(targetNode); } var caption = getAttribute(schemaNode, 'caption', null); var captionCell = null; if (caption && (argsNodeName !='.' || schemaNode != schemaRootNode)) { //if this table has at least one line then leave a blank line if (tableObj.rows.length && tableObj.rows.length > 0) { var row = tableObj.insertRow(-1); var cell = document.createElement('td'); cell.height = 20; row.appendChild(cell); } //create another table that would occupy entire cell of parent table's row var childTableObj = createTable(xpath2, null, 0, '100%'); //add caption for this child table // row = childTableObj.insertRow(); captionCell = row.insertCell(); captionCell.innerHTML = '

' + caption + '

'; captionCell.align = 'left'; captionCell.noWrap= true; row = tableObj.insertRow();//insert new row cell = row.insertCell(); cell.noWrap = true; cell.appendChild(childTableObj); tableObj = childTableObj; } for ( var childSchemaNode = schemaNode.firstChild; childSchemaNode; childSchemaNode = childSchemaNode.nextSibling) { var childName = childSchemaNode.nodeName; if (childName != "#comment" && childName != 'Buttons')//ignore comments and buttons { var showHideRow2 = addTableRows(tableObj, targetNode, childSchemaNode, xpath2, null);//false, false if (showHideRow2) showHideRow = showHideRow2; } } if (captionCell) captionCell.colSpan = findMaxTableColumns(childTableObj); } else//an attribute { var caption = getAttribute(schemaNode, 'caption', name); var row = tableObj.insertRow(); var cell = document.createElement('td'); //cell.style.padding=0; cell.innerHTML = '' + caption + ''; cell.width = '1%'; row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = ':'; cell.width = '1%'; row.appendChild(cell); var targetNode = objNode.selectSingleNode(name); if (!targetNode) { targetNode = xmlDoc.createElement(name); objNode.appendChild(targetNode); } showHideRow2 = insertAttribNodeInRow(tableObj, row, targetNode, schemaNode, xpath, 'left'); var ncells= row.cells.length; row.cells[ncells-1].width = '98%'; if (showHideRow2) showHideRow = showHideRow2; } } function populateTableRow(tableObj, row, domNode, schemaNode, strXPath, bRowCheckbox, bChecked) { var nodeName = domNode.nodeName; var lastRowIndex = tableObj.lastRowIndex ? parseInt(tableObj.lastRowIndex) + 1 : 0; tableObj.lastRowIndex = lastRowIndex.toString(); var showHideRow = null; if (bRowCheckbox) { row.id = strXPath + '.' + tableObj.lastRowIndex; //insert checkbox var col = row.insertCell(); var cbName = strXPath + ".checkbox"; //it is much faster to join a string array than assign concatenating strings // var innerHTML = new Array(); var i = 0; innerHTML[i++] = ' 0) { var firstRow = tableObj.rows[0].cells[; input.width=cell.clientWidth ? cell.clientWidth : 70; } */ } } if (b_static) { if (viewType == 'tooltip') { var len = targetNode.text.length; if (len <= 7) cell.innerText = targetNode.text; else { cell.innerText = targetNode.text.substring(0,4) + '...'; cell.onmouseover=function(){ EnterContent('ToolTip', null, targetNode.text, true); Activate();}; cell.onmouseout=deActivate; } } else if (dataType == 'boolean') { cell.innerText = targetNode.text; } else if (targetNode.text != '') { var colonPos = viewType.indexOf(':'); if (colonPos == -1)//not found cell.innerText = targetNode.text; else { var optionsArray = viewType.substring(colonPos+1).split('|'); cell.innerText = optionsArray[ targetNode.text ]; } } } cell.appendChild(input); //hack: somehow the checkboxes get unchecked after insertion into the cell so check 'em if (inputType=="checkbox") { if (input.value=="1" && !input.checked) input.checked = true; input.value = "1"; } return showHideRow; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- function createInputControlForNode(idPrefix, node, schemaNode, dataType, viewType, multiselect, columnHeader) { var id; var value; if (columnHeader) { id = multiselect ? multiselect.makeSetAllId(true) + '_0': null; value = null; } else { id = node.nodeName; value = node.text; if (value=="") value = getAttribute(schemaNode, 'default', ''); } var type; var checked = false; var input; var inputName = 'input'; var modifiedHandlerName = null; if ( viewType && (viewType == "hidden" || viewType.indexOf("static")==0 || viewType == "tooltip")) { type = "hidden"; if (columnHeader) { alert("Multiple selection is not supported for columns with controls of view type '" + viewType + "'!"); return null; } } else if (viewType == 'select') { type = "select"; inputName = 'select'; modifiedHandlerName = 'onchange'; } else if (viewType == 'showHideRowBtn') { if (columnHeader) { alert('Multiple selection is not supported for columns with toggle buttons!'); return null; } id += '.btn'; type = "button"; value = "Show"; } else if (dataType == "boolean") { type = "checkbox"; modifiedHandlerName = 'onclick'; if (value == "1" || value == "yes" || value=="true") checked = true; } else if (dataType == "file") { if (columnHeader) { alert('Multiple selection is not supported for columns with file controls!'); return null; } type = "file"; modifiedHandlerName = 'onclick'; } else { type = "text"; modifiedHandlerName = 'onchange'; } input = document.createElement(inputName); if (inputName == 'input') input.type = type; if (columnHeader) { input.title = type=='checkbox' ? "Select or unselect all items" : "Update all items in this column with this value"; input.id = id; } else { input.id = idPrefix ? (idPrefix + '.' + id) : id; input.name = input.id; input.value = value; } if (type == "checkbox") { if (checked) input.checked = true; } else if (type == 'text') { sz = getAttribute(schemaNode, 'size', null); if (sz) input.size = sz; } else if (viewType == 'select') { var source = getAttribute(schemaNode, 'source', null); if (source) { //we only support source == 'object' so far //optionTag defines tag name of child that defines an option var optionTag = getAttribute(schemaNode, 'option', 'option'); /* '@text', '@value' and '@selected' attributes of schemaNode hold the needed tag names which are used to populate the drop down list these are supposed to be child nodes of option node in object hierarchy for instance, the following schema node definition creates a select object from the object node below and selects second item: object node: ns1 val1 ns2 val2 true */ var textTag = getAttribute(schemaNode, 'text', null); var valueTag = getAttribute(schemaNode, 'value', null); var selectedTag = getAttribute(schemaNode, 'selected', null); if (node) { var options = node.selectNodes(optionTag); var n_options = options.length; for (var i=0; i 0) { for (var j=0; j < nBtns; j++) btns[j].disabled = !enable; } else break; } } function onAdd(nodeSetName) { //if (!addImmediateChildrenFromHtmlObjects(schemaRootNode, objRootNode, xmlDoc)) // return; updateNestedData("add", nodeSetName, -1); ms_reinitializeAll(); setModified(); } function onEdit(nodeSetName) { var index = getFirstCheckedItemIndex(nodeSetName); updateNestedData("edit", nodeSetName, index); setModified(); } function onDelete(nodeSetName, simulate) { var multiselect = ms_lookupByTableAndColumn(nodeSetName, 0); var index = getFirstCheckedItemIndex(nodeSetName); var rc = false; if (index == -1) alert("Please select one or more items to delete!"); else if (confirm('Are you sure you want to ' + (simulate ? 'remove' : 'delete') + ' the selected item' + (multiselect.getSelectionCount()!=1?'s':'') + '?')) { rc = true; while (rc && index != -1) { if (!updateNestedData("delete", nodeSetName, index, simulate)) rc = false; else index = getFirstCheckedItemIndex(nodeSetName, simulate ? index+1 : index); } if (!simulate) ms_reinitializeAll(); onRowCheck(multiselect.id); setModified(); } return rc; } function getFirstCheckedItemIndex(xpath, startIndex) { var ndx = -1; var checkBoxes = document.getElementsByName(xpath+".checkbox"); if (startIndex == undefined) startIndex = 0; //if we have only one checkbox then length is undefined in that case if (checkBoxes.length == undefined) { //we (un)checked the same checkbox so toggle selection if (checkBoxes.checked && startIndex == 0) ndx = 0; } else { var nCheckBoxes = checkBoxes.length; for (var i=startIndex; i 0; enableButton(tableId + ".Delete", anySelected); enableButtons(tableId + ".Edit", nSelected==1); if (!multiselect.b_singleSelect) enableButtons(tableId + ".MultiEdit", anySelected); onRowCheckHandler(multiselect); } function onColumnCheck(newValue, multiselect_id) { //the user checked on select all button one so we have at least one checkbox // //var multiselect = ms_lookup(multiselect_id); //var tableId = multiselect.o_table.id; } function onShowHideRow(tableId, rowId, srcObj, content) { var table = document.getElementById(tableId); var prevTableHt = table.offsetHeight; var srcObjId = srcObj.id; var toggleRowId = srcObjId + '.toggle'; var toggleRow = document.getElementById(toggleRowId); var bShow; var srcCell = srcObj.parentElement; var btnRow = document.getElementById(rowId);; //find out if btnRow has a checkbox in cell 0 // var nRowCheckbox = 0; var firstBtnRowCell = btnRow.cells[0]; var inputs = firstBtnRowCell.getElementsByTagName('INPUT'); var nInputs = inputs.length; for (var i=0; i'; } cell.innerHTML = content; toggleRowHt = toggleRow.offsetHeight; bShow = true; } else { bShow = toggleRow.style.display == 'none'; if (bShow) { toggleRow.style.display = 'block'; toggleRowHt = toggleRow.offsetHeight; } else { toggleRowHt = toggleRow.offsetHeight; toggleRow.style.display = 'none'; } } if (srcObj.type == 'button') { var pattern = bShow ? 'Show' : 'Hide'; var replace = bShow ? 'Hide' : 'Show'; srcObj.value = srcObj.value.replace( new RegExp(pattern), replace); } if (nRowCheckbox) { /*BUG in IE: document.getElementsByName(rowId + '.toggle') does not return any rows even though we may have just added one so use alternate implementation by enumerating rows (slower)*/ var toggleRowName = rowId + '.toggle'; var rowSpan = 1; var toggle_rows = table.getElementsByTagName('TR'); var n_toggle_rows = toggle_rows.length; for (i=0; i1 ? 'top' : 'center'; } var bDiv = document.getElementById( 'DB.' + tableId ); if (bDiv) { var divHt = bDiv.offsetHeight; bDiv.style.height = bShow ? (divHt + toggleRowHt+1) : divHt; } var resizeHandler = document.body.onresize; if (resizeHandler) resizeHandler(); } /* this function takes a string of the form "prefix{xpath}suffix" and returns prefixXYZsuffix, where XYZ is the result of execution of selectSingleNode(xpath). Multiple {xpath} blocks may be embedded within the string. This is primarily intended to substitute parameter values before form submission with resulting action. */ function expand_embedded_xpaths(str, schemaNode, node, bEscape) { var open_brace = str.indexOf('{'); if (open_brace == -1) return str; var close_brace = str.indexOf('}', open_brace+1); if (close_brace == -1) close_brace = str.length+1; var embraced = str.substring(open_brace+1, close_brace); var result; if (embraced.length) { if (embraced == '.') result = node.text; else { var targetNode = node.selectSingleNode(embraced); result = targetNode ? targetNode.text : embraced; } } else result = ''; return str.substring(0, open_brace) + (bEscape != false ? escape(result) : result) + expand_embedded_xpaths( str.substring(close_brace+1), schemaNode, node, bEscape ); } function updateItemList(tableObj, addItem, delItem, newValue) { var id = tableObj.id; id += ".itemlist"; var itemListInput = document.getElementById(id); if (itemListInput == null) { /* As per DHTML references in MSDN: The NAME attribute cannot be set at run time on elements dynamically created with the createElement method. To create an element with a name attribute, include the attribute and value when using the createElement method. */ itemListInput = document.createElement(""); itemListInput.id = id; itemListInput.value = "+"; document.forms[0].appendChild( itemListInput ); } if (addItem != null) itemListInput.value += addItem + '+'; else if (delItem != null) { var list = itemListInput.value; var pattern = '+' + delItem + '+'; var begin = list.indexOf(pattern); if (begin == -1) { alert("Table row management error!"); debugger; return false; } var end = begin + pattern.length -1; itemListInput.value = list.substring(0, begin) + list.substring(end); } else itemListInput.value = newValue; return true; } function setItemListFromSelectedRowsOnly(tableId) { var checkBoxes = document.getElementsByName(tableId+".checkbox"); var nCheckBoxes = checkBoxes.length; var itemList='+'; for (var i=0; i as prefix // var s_array = xpath_slashes.split('/'); for (var i = 0; i< s_array.length-1; i++) { xml[j++] = '<'; xml[j++] = s_array[i]; xml[j++] = '>'; } for (var i=0; i
as suffix // for (var i = s_array.length-2; i>=0 ; i--) { xml[j++] = ''; } return xml.join(''); } function findMaxTableColumns(tableObj) { var nColsMax = 0; var rows = tableObj.rows; var nRows = rows.length; for (var i=0; i nColsMax) nColsMax = nCols; } return nColsMax; } // this is a place holder to be redefined by the component's command // if special handling is needed upond modified state change // function onDocumentModified(modified) { } function setModified(val) { if (document.modified != val) { document.modified = val != undefined ? val : true; onDocumentModified(val); } } function setModifiedHandler(schemaNode, node, htmlObj, handlerName, multiselect, columnHeader) { var handlerAttrib = getAttribute(schemaNode, handlerName, null); var handlerScript = new Array(); var i = 0; handlerScript[i++] = 'setModified(); '; if (multiselect) { handlerScript[i++] = columnHeader ? 'ms_setAll' : 'ms_onChange'; handlerScript[i++] = "(this, '"; handlerScript[i++] = multiselect.tableId; handlerScript[i++] = "',"; handlerScript[i++] = multiselect.n_column; handlerScript[i++] = '); '; if (multiselect.n_column > 0 && columnHeader) handlerScript[i++] = "this.style.display = 'none'"; } if (handlerAttrib && node) handlerScript[i++] = expand_embedded_xpaths( handlerAttrib, schemaNode, node); if (handlerName == 'onclick') htmlObj.onclick = new Function(handlerScript.join('')); else if (handlerName == 'onchange') htmlObj.onchange = new Function(handlerScript.join('')); } function onBeforeUnloadDocument() { //null; //don't let IE display any dialog box...any string value returned makes IE do so //window.event.cancelBubble = document.modified && !confirm('Are you sure you want to lose changes to this web page?'); if (document.modified) event.returnValue = 'All changes will be lost!'; } function disableSubmitButtons(disable) { if (typeof disable == 'undefined') disable = true; //enable/disable all submit buttons: var inputs = document.getElementsByTagName('INPUT'); var nInputs = inputs.length; for (var i=0; i