/* * Class representing a controller to communicate between the view and the model. */ var CoreController = Class.create(); CoreController.prototype = { initialize: function(){ this.resources = new Resources(); this.performingFind = false; /** * The main report object associated with this controller */ this.reportInstance = new Report(this, this._getUniqueId()); this.credentialManager = new CredentialManager(this); this.printControllerInstance = new PrintController(this._getUniqueId()); this.exportControllerInstance = new ExportController(this); this.navigateControllerInstance = new NavigateController(this); this.findControllerInstance = new FindController(this); this.selectedBooleanParameters = new Array(); this.invalidParameters = new Array(); var reportViewer = document.getElementById(this.buildUniqueString('reportViewerControlPanel')); if(reportViewer!=null) this.usingReportViewer = true; else this.usingReportViewer = false; }, /* * Utility function to return the uniqueId parameter being used to identify the class. */ _getUniqueId: function(){ return 'RepViewer$coreViewer'; }, /** * Utility function to create a string with with the prefix and appended uniqueId being used for the class */ buildUniqueString: function(prefix){ return prefix + this._getUniqueId(); }, /* * Function replaces incorrect URL symbols by its equivalent */ fixURL: function(url){ // url replacement symbols // " # % & ' * , : ; < > ? [ ] ^ ` { | } // %22 %23 %25 %26 %27 %2a %2c %3a %3b %3c %3e %3f %5b %5d %5e %60 %7b %7c %7d %20 url = url.replace(/\#/g, '%23'); url = url.replace(/\n/g, ''); return url; }, /* * Function call to search a report using ajaxSendRequest. * Parameter: url - is the url for the ajax request to use when sending the request. * The url should have the refresh parameter command in it. */ refreshParameters: function(url){ url = this.fixURL(url); DiagContext.traceVerbose('CoreController: Refresh Parameter ' + url); this.toggleParameterLoadingImage(true); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.reportInstance.parameters), 0); }, /** * Submits current credentials on this report instance to the server and attempts to refresh/review the report. * This is called by the CredentialsDialog after CredentialsDialog already udpated the this.reportInstance's credential information. */ submitCredentialsToServer: function() { DiagContext.traceVerbose('CoreController: submitCredentialsToServer'); /* I AM AFLICTED BY THIS FF BUG since we call this from a popup: https://bugzilla.mozilla.org/show_bug.cgi?id=317600 * using setTimout as a potential workaround */ var delay = 0; var uniqueID = this._getUniqueId(); //note use of bind: http://blog.livollmers.net/?p=17 window.setTimeout( this.submitCredentialsToServer_MozillaBugWorkaround.bind(this), delay); }, /** * I AM AFLICTED BY THIS FF BUG since we call this from a popup: https://bugzilla.mozilla.org/show_bug.cgi?id=317600. Using this function via setTimout as workaround. */ submitCredentialsToServer_MozillaBugWorkaround: function() { // get this funky URL that contains all the current state of the report: this.reportInstance.currentUrl = this.reportInstance._buildUrl(); // prepare credentials data to send to the server: var requestParameters = "credentailsXml=" + escape(this.credentialManager.getCredentalsXmlData()); var url = "/CoreHandler.ashx?" + this.reportInstance.currentUrl + "&rs:Command=SubmitCredentials&dd:forceHttps=False"; var myRequest = new Ajax.Request(url, { onSuccess: this.onSubmitCredentialsToServerCallback.bind(this), onFailure: function() { DiagContext.traceError("failure occured while submitting credentials."); }, parameters: requestParameters }); }, /** * Used in #submitCredentialsToServer as the callback function when the request succeeds. */ onSubmitCredentialsToServerCallback: function() { // so we submitted the latest credentials to the server. // all we really need to do here is refresh the report. this.reportInstance.refreshReport(); }, /* * Function call to search a report using ajaxSendRequest. * Parameter: Url - is the url for the ajax request to use when sending the request. * The url should have the find command in it. */ searchReport: function(url){ url = this.fixURL(url); DiagContext.traceVerbose('CoreController: Search Report ' + url); this.toggleFindLoadingImage(true); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.findControllerInstance), 0); }, /* * Updates the inner HTML for the find results panel with the results of the search. * Parameter: html - the html returned from the search command handler. */ updateSearchResults: function(html){ var elem = document.getElementById('FindResultPanelRepViewer$coreViewer'); elem.innerHTML = html; this.toggleFindLoadingImage(false); }, /* *Function call to load a report using ajaxSendRequest. *Parameter: Url - is the url for the ajax request to use when sending the request. */ loadReport: function(url){ currentTime = new Date(); url = this.fixURL(url); DiagContext.traceVerbose('load report ' + url + ' for ' + this._getUniqueId() + ' ' + currentTime.getMinutes() + ':' + currentTime.getMilliseconds()); this.toggleReportLoadingImage(true); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.reportInstance), 0); }, /* * Function call to print a report using ajaxSendRequest. * Parameter: url - is the url for the ajax request to use when sending the request. * The url should have the print command in it. */ printReport: function(url){ url = this.fixURL(url); DiagContext.traceVerbose('Controller: printReport ' + url); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.printControllerInstance), 0); }, /* * Function call to cancel a report using ajaxSendRequest. * Parameter: url - is the url for the ajax request to use when sending the request. * The url should have the cancel command in it. */ cancelReport: function(url){ url = this.fixURL(url); DiagContext.traceVerbose('Controller: cancelReport ' + url); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.reportInstance), 0); }, /* * Function call to export a report to a particular format using ajaxSendRequest. * Parameter: url - the url for the ajax request to use when sending the request. * the url should have the export command in it. */ exportReport: function(url){ url = this.fixURL(url); DiagContext.traceVerbose('Controller: exportReport ' + url); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.exportControllerInstance), 0); }, /* * Function call to navigate to an URL using ajaxSendRequest. * Parameter: url - the url for the ajax request to use when sending the request. * the url should have the navigate command in it. */ navigateCommand: function(url){ url = this.fixURL(url); DiagContext.traceVerbose('Controller: navigateCommand ' + url); window.setTimeout(this.ajaxSendRequest.bind(this, url, this.navigateControllerInstance), 0); }, /* * Reads the values from the hidden controlState control for the attached core panel control and sets up the * report. After reading in the set values it loads the report. This is called when the page loads. */ loadPageValues: function(){ DiagContext.traceVerbose('loading page values'); var stateValues = document.getElementById(this.buildUniqueString('controlState')); if(stateValues!=null){ var entries = stateValues.value.split(';'); for(var i=0;i= 9) { // For IE9 and up clear method is not currently supported. Workaround provided on MSDN. iframeDocument.write(""); iframeDocument.close(); iframeDocument.open(); } else { iframeDocument.clear(); } iframeDocument.writeln(html); iframeDocument.close(); /* If any parent container of the web viewer is right to left then the html document in the iframe needs to have the dir attribute set so the browser will look and function right to left. */ var dir = this._getIFrameDirection(iframeElement); if(dir){ if(!iframeDocument.documentElement.dir){ iframeDocument.documentElement.dir = dir; } if(iframeDocument.documentElement.dir == "rtl"){ this._adjustIFrameDocumentRTL(iframeDocument); } } var target = this.reportInstance.target; this.reportInstance.target = ""; if(target.length>0){ var targetElement = iframeDocument.getElementById(target); if(targetElement!=null) targetElement.scrollIntoView(true); return; } var linkTarget = iframeDocument.getElementById('FindTarget'); if(linkTarget !=null) linkTarget.scrollIntoView(true); iframeElement.frameborder = 0; iframeElement.style.borderWidth = '0px'; DiagContext.traceVerbose('IFrame frameborder ' + iframeElement.frameborder); } catch(exception){ DiagContext.traceError('error filling iframe: ' + iframeElement + ' ' + exception.description); } }, /* * Find the closest parent of the iframe with the dir attribute or direction style property set. */ _getIFrameDirection: function(iframeElement){ var parent = iframeElement; var dir; while(parent){ if(parent.dir){ dir = parent.dir; break; } if(parent.style.direction){ dir = parent.style.direction; break; } parent = parent.parentElement; } return dir; }, /* * The document comes in with page sections set with absolute positions. When the container is * right to left and the content is wider than the container the page section is scrolled right * and the left edge is set to the visible area left instead of the container left. * A solution that works in all supported browsers is to determine the furthest right child of * all page sections and set all page sections to that width. Then letting the browser determine the * body width and page sections left automatically. */ _adjustIFrameDocumentRTL: function(iframeDocument){ var pageSections = iframeDocument.body.children[0].children[0].children; var contentRight = 0; for (var i = 0; i < pageSections.length; i++){ var pageSection = pageSections[i]; for (var j = 0; j < pageSection.children.length; j++){ var child = pageSection.children[j]; contentRight = Math.max(contentRight,child.offsetLeft + child.offsetWidth); } } var contentDoesNotFit = contentRight > iframeDocument.body.clientWidth; for (var i = 0; i < pageSections.length; i++){ var pageSection = pageSections[i]; if(contentDoesNotFit){ pageSection.style.left = 'auto'; }else{ pageSection.style.left = '0px'; } pageSection.style.width = contentRight; } if(contentDoesNotFit){ iframeDocument.body.style.width = 'auto'; }else{ iframeDocument.body.style.width = ''; } }, /* * Adjusts the core iframe, if necessary. */ _updateForResize: function(isPdf){ if(isPdf){ return; } var iframeElement = document.getElementById(this.buildUniqueString('CorePanel')); var iframeDocument; if (jQuery.browser.mozilla && iframeElement.contentDocument) { // For FF iframeDocument = iframeElement.contentDocument; } else if (iframeElement.contentWindow) { // For IE5.5 and up, Chrome iframeDocument = iframeElement.contentWindow.document; } else { alert("Error: could not find iframe document"); return; } if(iframeDocument.documentElement.dir == "rtl"){ this._adjustIFrameDocumentRTL(iframeDocument); } }, /* * Under IE you can't make changes to the document once you've created it so this will replace * the current iframe with a new one so switching viewer types will work correctly. */ _resetIFrame: function(iframeElement){ var parentElement = iframeElement.parentElement; var newIFrameElement = document.createElement("iframe"); newIFrameElement.id = iframeElement.id; newIFrameElement.name = iframeElement.name; newIFrameElement.style.width = "100%"; newIFrameElement.height = iframeElement.clientHeight; parentElement.removeChild(iframeElement); parentElement.appendChild(newIFrameElement); return newIFrameElement; }, /** * Set's the html and activates the TOC script for the document map panel. */ _setDocumentMapPanel: function(){ //TODO: Need to add some logic to only set the html when the document map //html has changed (or possibly changes) this._setDocMapDisplay(''); if(this.report.hasDocumentMap){ var docPanel = document.getElementById(this.buildUniqueString('documentMapArea')); if(docPanel == null){ DiagContext.traceWarning('Could not find a document map panel control'); return; } docPanel.innerHTML = this.report.documentMapHtml; makeTocInteractive(docPanel); } }, /* * Attached the find button to the findText event */ _setupFindPanel: function(){ var button = document.getElementById(this.buildUniqueString('btnFindText')); if(button != null){ button.onclick = this.findText.bind(this); } button = document.getElementById(this.buildUniqueString('btnAdvancedSearch')); if(button != null){ button.onclick = this.toggleSearchOptions.bind(this); } button = document.getElementById(this.buildUniqueString('btnClearSearch')); if(button != null){ button.onclick = this.clearFindPanel.bind(this); } }, /* * Sets up the Page N of M text and label controls in the toolbar. */ _setupPageNofM: function(format){ var isPdf = format == "Pdf"; pageTextbox = document.getElementById(this.buildUniqueString('ddTbPage')); if(pageTextbox!=null){ if(isPdf){ pageTextbox.style.display = "none"; } else{ pageTextbox.style.display = ""; pageTextbox.value = this.report.pageNumber; pageTextbox.onkeypress = this.validatePageInput.bind(this); if(this.report.pageCount < 1) pageTextbox.disabled = true; else pageTextbox.disabled = false; } } pageCountLbl = document.getElementById(this.buildUniqueString('ddLblPageCount')); if(pageCountLbl != null){ if(isPdf){ pageCountLbl.style.display = "none"; } else{ pageCountLbl.style.display = ""; pageCountLbl.innerHTML = ' '; pageCountLbl.innerHTML = this.report.pageCount; } } pageLabelOf = document.getElementById(this.buildUniqueString('ddLblOf')); if(pageLabelOf != null){ if(isPdf){ pageLabelOf.style.display = "none"; } else{ pageLabelOf.style.display = ""; } } }, /* * Sets up the visible state for the line spacers in the toolbar based off of the format. */ _setupLineSpacers: function(format){ var isPdf = format == "Pdf"; printLineSpacer = document.getElementById(this.buildUniqueString('ddLineSpacerPrint')); if(printLineSpacer != null){ if(isPdf){ printLineSpacer.style.display = "none"; } else{ printLineSpacer.style.display = ""; } } pageNavigationLineSpacer = document.getElementById(this.buildUniqueString('ddLineSpacerPageNavigation')); if(pageNavigationLineSpacer != null){ if(isPdf){ pageNavigationLineSpacer.style.display = "none"; } else{ pageNavigationLineSpacer.style.display = ""; } } }, /* * Attaches an onchange event to the viewer mode select control on the toolbar */ _setupViewerModeCombo: function(){ viewerModeCombo = document.getElementById(this.buildUniqueString('ddCmbViewerMode')); if(viewerModeCombo != null){ viewerModeCombo.onchange = this.viewerModeChanged.bind(this); } }, /* * Attaches an onchange event to the zoom select control on the toolbar. */ _setupZoomCombo: function(format){ var isPdf = format == "Pdf"; zoomCombo = document.getElementById(this.buildUniqueString('ddCmbZoom')); if(zoomCombo!=null){ if(isPdf){ zoomCombo.style.display = "none"; } else{ zoomCombo.style.display = ""; zoomCombo.onchange = this.zoomChanged; } } }, /* * Starts the process of putting together the dynamic parameter UI panel. * Parameter: parameters is the parameters collection from the report class. */ _buildParameterPanel: function(parameters){ try{ DiagContext.traceVerbose('CoreController: _buildParameterPanel started, parameter count=' + parameters.length); inputSpan = document.getElementById(this.buildUniqueString('ParameterInputArea')); var cellCount = 0; var dateTimeParameterIds = new Array(); if(inputSpan != null && parameters.length>0){ var div = document.createElement("div"); div.id = "parametersList"; var newPanel = false; for(var i =0;i0){ value = parameter.defaultValues[0].value; } } var selected = false; for(var validValueIndex=0;validValueIndex 0) ? parameterValidValue.label : validValue; var option = new Option(validLabel, validValue); option.title = validLabel; if(parameter.state != 'MissingValidValue'){ for(var valueIndex=0;valueIndex0){ value = parameter.defaultValues[0].value; } } var falseSelected = (value=="False") ? true : false var trueSelected = (value=="True") ? true : false if (value != null && value != ''){ control.checked = trueSelected; control = document.getElementById('f'+this._getParameterIdFromIndex(i)); if(control!=null){ control.checked = falseSelected; } } } else{ if(parameter.multiValue){ var value = ""; for(var i=0;i0){ value = parameter.defaultValues[0].value; } } } if(parameter.nullable){ var nullCheckboxId = "null" + id; var checkBox = document.getElementById(nullCheckboxId); checkBox.checked = value == null; control.disabled = checkBox.checked; } if(parameter.dataType == 'DateTime') { if(parameter.dateOnly){ if(control.value != value){ var datePickerId = "#" + id.replace(/\$/g, "\\$"); if(value != null){ var newDTValue = jQuery.datepicker.parseDate('yy-mm-dd', value); jQuery(datePickerId).datepicker("setDate", newDTValue); } else{ jQuery(datePickerId).val(''); } } } else{ var timeControl = document.getElementById("Time" + id); var controlValue = control.value + ' ' + timeControl.value; timeControl.disabled = control.disabled; if(controlValue != value){ var datePickerId = "#" + id.replace(/\$/g, "\\$"); if(value != null){ var dateTime = value.split(' '); var newDTValue = jQuery.datepicker.parseDate('yy-mm-dd', dateTime[0]); jQuery(datePickerId).datepicker("setDate", newDTValue); if(dateTime.length>1) timeControl.value = dateTime[1]; } else{ jQuery(datePickerId).val(''); timeControl.value = ''; } } } } else{ if(control.value != value){ if(value != null){ control.value = value; } else{ control.value = ''; } } } } if(parameter.nullable){ var prefix = "null"; if(parameter.dataType == "Boolean"){ prefix += "bool"; } var nullCheckboxId = prefix + id; var control = document.getElementById(nullCheckboxId); if(control.checked){ parameter.value = null; } } } else{ newPanel = true; var idForParameterInput = this._getParameterIdFromIndex(i); var control = this._getParameterControl(parameter, idForParameterInput); if(parameter.dataType == 'DateTime') dateTimeParameterIds[dateTimeParameterIds.length]=idForParameterInput.replace(/\$/g, "\\$"); div.appendChild(control); div.appendChild(document.createElement('br')); } } } if(newPanel){ DiagContext.traceVerbose('wrapping up table'); inputSpan.innerHTML = ''; inputSpan.appendChild(div); var cultureInfo = jQuery.ajax({ type:"GET", url:"/CoreHandler.ashx?rs:Command=GetCultureInfo&reportLanguage="+this.reportInstance.reportLanguage, async: false }).responseText; if(jQuery.browser.msie){ var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.loadXML(cultureInfo); cultureInfo = xmlDoc; } var datepickerCulture = $(cultureInfo).find('name').text(); var amDesignatorCulture = $(cultureInfo).find('amDesignator').text(); var pmDesignatorCulture = $(cultureInfo).find('pmDesignator').text(); var timeSeparatorCulture = $(cultureInfo).find('timeSeparator').text(); var datepickerRegion = jQuery.datepicker.regional[datepickerCulture]; if(datepickerRegion == undefined) datepickerCulture = ""; jQuery.datepicker.setDefaults( jQuery.datepicker.regional[ datepickerCulture ] ); for(var pi = 0; pi0){ var id = this.selectedBooleanParameters.pop(); var elem = document.getElementById(id); elem.checked = true; } } else { inputSpan.innerHTML = ''; } parameterButton = document.getElementById(this.buildUniqueString('btnViewReport')); if(parameterButton !=null){ if(parameters.length>0){ parameterButton.onclick = this.refreshReport.bind(this); parameterButton.disabled = false; } else{ parameterButton.disabled = true; } } DiagContext.traceVerbose('CoreController: _buildParameterPanel finished'); } catch(exception){ DiagContext.traceError('Error building parameter panel: ' + exception.description); } }, /* * Clears dynamic parameter UI panel. */ _clearParameterPanel : function() { inputSpan = document.getElementById(this.buildUniqueString('ParameterInputArea')); if (inputSpan != null) { inputSpan.innerHTML = ''; } }, /* * A helper function the checks the parameters to see if any of them have a state this is not valid. * returns true if all parameters are valid; otherwise false. */ _areParameterStatesValid: function(parameters){ var res = true; var parametersList = document.getElementById('parametersList'); for(var parameterIndex=0; parameterIndex 0) ? validValue.label : validValue.value; option = new Option(optionText, optionValue); option.title = optionText; var selected = false; if(optionValue == value){ selected = true; } select.options.add(option); //Set the selected after adding because IE doesn't honor it if you don't option.selected = selected } if(parameter.nullable){ var nullSpan = document.createElement("span") nullSpan.className = 'sideBarText'; var checkBox = document.createElement("input"); checkBox.id = 'null'+id; checkBox.onclick = this.setNullable.bind(this); checkBox.type = 'checkbox'; checkBox.className = 'sideBarCheckbox'; checkBox.checked = parameter.value == null; checkBox.name = id; select.disabled = parameter.value == null; nullSpan.appendChild(checkBox); var nullText = document.createTextNode("Null"); nullSpan.appendChild(nullText); span.appendChild(nullSpan); } var validationMessage = document.createElement("div"); validationMessage.className = "validationMessage"; validationMessage.id = 'valMessage'+id; // When we create parameters controls at the first time, do not add validation message // according to case 36568. span.appendChild(validationMessage); return span; }, /* * Retuns a boolean radio button control set for a parameter. */ _getBooleanParameterControl: function(parameterName, parameter, id){ try { var prompt = parameter.prompt; if(prompt == null|| prompt == ""){ prompt = parameterName; } var value = parameter.value; if(value == null || value == ""){ if(parameter.defaultValues != null && parameter.defaultValues.length==1){ value = parameter.defaultValues[0].value; } } if(value == null){ var valueIsNull = true; value = ""; } var falseSelected = (value=="False") ? true : false var trueSelected = (value=="True") ? true : false var span = document.createElement("div"); span.className = 'parameter'; var promptSpan = document.createElement("span"); promptSpan.className = "parameterPrompt"; var promptText = document.createTextNode(prompt); promptSpan.appendChild(promptText); span.appendChild(promptSpan); span.appendChild(document.createElement("br")); var radioSpan = document.createElement("span"); radioSpan.className = 'booleanParameter'; var input = document.createElement("input"); input.className = 'parameterRadio'; input.name = parameterName; input.onclick = this.parameterSelectionChanged.bind(this); input.id ='t'+id; if(valueIsNull || parameter.nullable){ input.disabled = true; } if(trueSelected)//Can't set checked until the control gets added to the document. this.selectedBooleanParameters.push(input.id); input.type='radio'; input.value ='True'; radioSpan.appendChild(input); var valueText = document.createTextNode('True'); radioSpan.appendChild(valueText); span.appendChild(radioSpan); radioSpan = document.createElement("span"); radioSpan.className = 'booleanParameter'; input = document.createElement("input"); input.className = 'parameterRadio'; input.name = parameterName; input.onclick = this.parameterSelectionChanged.bind(this); input.id ='f'+id; if(valueIsNull || parameter.nullable){ input.disabled = true; } if(falseSelected)//Can't set checked until the control gets added to the document. this.selectedBooleanParameters.push(input.id); input.type='radio'; input.value = 'False'; radioSpan.appendChild(input); var valueText = document.createTextNode('False'); radioSpan.appendChild(valueText); span.appendChild(radioSpan); if(parameter.nullable){ var nullSpan = document.createElement("span") nullSpan.className = 'booleanParameter'; var checkBox = document.createElement("input"); checkBox.id = 'nullbool'+id; checkBox.onclick = this.setNullable.bind(this); checkBox.type = 'checkbox'; checkBox.checked = parameter.value == null; checkBox.name = id; nullSpan.appendChild(checkBox); var nullText = document.createTextNode("Null"); nullSpan.appendChild(nullText); span.appendChild(nullSpan); } var validationMessage = document.createElement("div"); validationMessage.className = "validationMessage"; validationMessage.id = 'valMessage'+id; // When we create parameters controls at the first time, do not add validation message // according to case 36568. span.appendChild(validationMessage); return span; } catch(exception){ DiagContext.traceVerbose('Boolean Parameter Error: ' + exception.description); } }, /* * Returns a Datatime control for a parameter */ _getDateTimeParameterControl: function(parameterName, parameter, id){ //TODO: consider the need for a special control for integer return this._getStringParameterControl(parameterName, parameter, id, true); }, /* * Returns a float input control for a parameter */ _getFloatParameterControl: function(parameterName, parameter, id){ //TODO: consider the need for a special control for integer return this._getStringParameterControl(parameterName, parameter, id, false); }, /* * Returns an integer input control for a parameter */ _getIntegerParameterControl: function(parameterName, parameter, id){ //TODO: consider the need for a special control for integer return this._getStringParameterControl(parameterName, parameter, id, false); }, /* * Returns an string input control for a parameter */ _getStringParameterControl: function(parameterName, parameter, id, isDateTime){ var prompt = parameter.prompt; if(prompt == null || prompt == ""){ prompt = parameterName; } var value = parameter.value; if(value == null || value == ""){ if(parameter.defaultValues != null && parameter.defaultValues.length==1){ value = parameter.defaultValues[0].value; } } if(parameter.multiValue){ value = ""; for(var i=0;i option was selected from the list of valid values. // in this case we should prevent validation message to be shown. if(selectionControl && !parameter.allowBlank && parameter.value == ''){ return ''; } var state = parameter.state; //TODO: Need to create a RESX command handler so this stuff can come from a resource file. if(state == 'HasValidValue'){ return ''; } else if(state == 'DynamicValuesUnavailable'){ return this.resources.getDynamicValuesUnavailableMessage(); } else if(state == 'HasOutstandingDependencies'){ return this.resources.getHasOutstandingDependenciesMessage(); } else if(state == 'MissingValidValue'){ return this.resources.getMissingValidValueMessage(); } }, /* * Handles enabling toolbar buttons based off of the current report's state and * attaching event handlers to the toolbar buttons if need * buttonId: the id for the button to attached events to and set enabled state for. */ _enableToolbarButton: function(buttonId, format){ try{ var button = document.getElementById(buttonId); if(button == null){ DiagContext.traceWarning('Attempting to setup button ' + buttonId + ' but this button does not exist'); } this._attachButtonEvents(button); this._setEnabledAndVisibleStates(button, format); } catch(exception){ DiagContext.traceError('Error enabling toolbar ' + exception.description); } }, _enableExportCombo: function(){ try{ var comboID = 'ddCmbExport'; var combo = document.getElementById(this.buildUniqueString(comboID)) if (combo == null){ DiagContext.traceWarning('Attempting to setup combo ' + comboID + ' but this combo does not exist'); } combo.onchange = this.performExport.bind(this); } catch(exception){ DiagContext.traceError('Error enabling toolbar ' + exception.description); } }, /* *sets the enable state for a button based off of the current report's state. *button: the button element to set the enabled state for. */ _setEnabledAndVisibleStates: function(button, format){ var isPdf = format == "Pdf"; //TODO: need to look over the disable code because //disabling the buttons cases them to move to the center of the //toolbar var pageNumber = this.report.pageNumber - 0; var pageCount = this.report.pageCount - 0; if(button.id.indexOf("ddBtnBackToParent")>-1){ if(this.report.getDrillThroughHistoryCount()>0){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnFirst")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageNumber > 1){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnNext")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageNumber < pageCount){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnPrevious")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageNumber>1){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnLast")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageNumber < pageCount){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnDocMap")>-1){ var sideBar = document.getElementById(this.buildUniqueString('reportViewerSideBar')); var hiddenSidebar = sideBar.className == "hiddenSideBar"; var reportLoaded = this.report != null; if(hiddenSidebar && reportLoaded){ enable(button); } else if(pageCount>0 || isPdf){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnPrint")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageCount>0){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnRenderMode")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageCount>0){ enable(button); if (this.reportInstance.renderMode == "Paginated") { sink(button); } else { unsink(button); } } else{ disable(button); } return; } if(button.id.indexOf("ddBtnExport")>-1){ if(pageCount>0 || isPdf){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnEmail")>-1){ if(pageCount>0 || isPdf){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnPageSetup")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageCount>0){ enable(button); } else{ disable(button); } return; } if(button.id.indexOf("ddBtnShowDocMap")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(this.report.hasDocumentMap){ enable(button); } else{ disable(button); } } if(button.id.indexOf("ddBtnShowFindPanel")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(pageCount>0){ enable(button); } else{ disable(button); } } if(button.id.indexOf("ddBtnShowParameterPanel")>-1){ if(isPdf){ button.style.display = "None"; return; } else{ button.style.display = ""; } if(this.report.hasParameters){ enable(button); } else{ disable(button); } } /* disable at startup since it's always the same mode*/ if(button.id.indexOf("ddBtnViewerMode")>-1){ disable(button) } }, /* * Attached an events to a button based off of the button's id * button: the button to attach events to. */ _attachButtonEvents: function(button) { if(button.onmouseover == null){ button.onmouseover = doOver; } if(button.onmousedown == null){ button.onmousedown = doDown; } if(button.onmouseup == null){ button.onmouseup = doUp; } if(button.onmouseout == null){ button.onmouseout = doOut; } if(button.onclick == null){ if(button.id.indexOf("ddBtnBackToParent")>-1){ button.onclick = this.backToParent.bind(this); return; } if(button.id.indexOf("ddBtnFirst")>-1){ button.onclick = this.firstPage.bind(this); return; } if(button.id.indexOf("ddBtnNext")>-1){ button.onclick = this.nextPage.bind(this); return; } if(button.id.indexOf("ddBtnPrevious")>-1){ button.onclick = this.previousPage.bind(this); return; } if(button.id.indexOf("ddBtnLast")>-1){ button.onclick = this.lastPage.bind(this); return; } if(button.id.indexOf("ddBtnRenderMode")>-1){ button.onclick = this.toggleRenderMode.bind(this); return; } if(button.id.indexOf("ddBtnEmail")>-1){ button.onclick = this.openEmailDialog.bind(this); return; } if(button.id.indexOf("ddBtnPrint")>-1){ button.onclick = this.print.bind(this); return; } if(button.id.indexOf("ddBtnCancel")>-1){ button.onclick = this.cancel.bind(this); return; } if(button.id.indexOf("ddBtnPageSetup")>-1){ if(this.reportInstance.hasPageInfo){ button.onclick = this.openPageSetupDialog.bind(this); } return; } if(button.id.indexOf("ddBtnExport")>-1){ button.onclick = this.performExport.bind(this); return; } if(button.id.indexOf("ddBtnDocMap")>-1){ if(!this.usingReportViewer){ button.onclick = this.toggleDocMap.bind(this); return; } button.onclick = this.toggleSideBar.bind(this); } if(button.id.indexOf("ddBtnShowDocMap")>-1){ button.onclick=this.showDocMapSideBar.bind(this); return; } if(button.id.indexOf("ddBtnShowFindPanel")>-1){ button.onclick = this.showFindSideBar.bind(this); return; } if(button.id.indexOf("ddBtnShowParameterPanel")>-1){ button.onclick = this.showParameterSideBar.bind(this); return; } if(button.id.indexOf("ddBtnViewerMode")>-1){ button.onclick = this.setViewerMode.bind(this); return; } } }, /* * onclick Event responsible for navigating to the next report page */ nextPage: function(){ var newPage = this.reportInstance.pageNumber; newPage++; if(newPage > this.reportInstance.pageCount){ newPage = this.reportInstance.pageCount; } this.reportInstance.gotoPage(newPage); }, /* * Navigates back up through the drillthrough history stack to get the parent report from inside * a drilled through report. */ backToParent: function(){ this._clearParameterPanel(); this.reportInstance.gotoParent(); }, /* * onclick event responsible for navigating to the first report page. */ firstPage: function(){ this.reportInstance.gotoPage(1); }, /* * onclick event responsible for navigating to the previous report page. */ previousPage: function(){ var newPageNumber = this.reportInstance.pageNumber - 1; if(newPageNumber>0){ this.reportInstance.gotoPage(newPageNumber); } }, /* * onclick event responsible for navigating to the last page of a report. */ lastPage: function(){ var newPage = this.reportInstance.pageCount; this.reportInstance.gotoPage(newPage); }, /* * onclick event to toggle the render mode from paginated to gally. */ toggleRenderMode: function(){ this.reportInstance.toggleRenderMode(); }, /* Support Script for forced modal dialogs with Netscape*/ ignoreEvent: function(e){ return false; }, handleFocus: function(){ if (winModalWindow){ if (!winModalWindow.closed){ winModalWindow.focus(); } else{ window.top.releaseEvents (Event.CLICK|Event.FOCUS); window.top.onclick = ""; } } return false; }, /*End modal dialog support scripts*/ /* * Shows the email dialog panel. */ openEmailDialog: function(){ if(window.showModalDialog){ window.showModalDialog("/CoreHandler.ashx?rs:Command=GetResourceItem&ResourceName=Email.html&uniqueId=RepViewer$coreViewer&dd:forceHttps=False",this,"center=yes;border=thick;dialogHeight=312px;dialogWidth=280px"); } else{//Netscape doesn't support showModalDialog so we have to create our own. window.top.captureEvents (Event.CLICK|Event.FOCUS); window.top.onclick=this.IgnoreEvents; window.top.onfocus=this.HandleFocus; winModalWindow = window.open ("/CoreHandler.ashx?rs:Command=GetResourceItem&ResourceName=Email.html&uniqueId=RepViewer$coreViewer&dd:forceHttps=False", this.resources.getEmailDialogTitle(),"dependent=yes,resizable=no,height=290px,width=280px"); winModalWindow.focus(); } }, /* * Shows the page setup dialog panel */ openPageSetupDialog: function(){ if(window.showModalDialog){ window.showModalDialog("/CoreHandler.ashx?rs:Command=GetResourceItem&ResourceName=PageSetup.html&uniqueId=RepViewer$coreViewer&dd:forceHttps=False",this, "center=yes;border=thick;dialogHeight=280px;dialogWidth=426px"); } else{//Netscape doesn't support showModalDialog so we have to create our own. window.top.captureEvents (Event.CLICK|Event.FOCUS); window.top.onclick=this.IgnoreEvents; window.top.onfocus=this.HandleFocus; winModalWindow = window.open ("/CoreHandler.ashx?rs:Command=GetResourceItem&ResourceName=PageSetup.html&uniqueId=RepViewer$coreViewer&dd:forceHttps=False", this.resources.getPageSetupDialogTitle(),"dependent=yes,resizable=no,height=228px,width=410px"); winModalWindow.focus(); } }, openCredentialsDialog: function() { if(window.showModalDialog){ window.showModalDialog("/CoreHandler.ashx?rs:Command=GetResourceItem&ResourceName=CredentialsDialog.html&uniqueId=RepViewer$coreViewer&dd:forceHttps=False",this, "center=yes;border=thick;dialogHeight=228px;dialogWidth=410px"); } else {//Netscape doesn't support showModalDialog so we have to create our own. window.top.captureEvents (Event.CLICK|Event.FOCUS); window.top.onclick=this.IgnoreEvents; window.top.onfocus=this.HandleFocus; winModalWindow = window.open ("/CoreHandler.ashx?rs:Command=GetResourceItem&ResourceName=CredentialsDialog.html&uniqueId=RepViewer$coreViewer&dd:forceHttps=False", this.resources.getCredentialsDialogTitle(),"dependent=yes,resizable=no,height=228px,width=410px"); winModalWindow.focus(); } }, /* * oncick event responsible for handling the toolbar's print button click. */ print: function(){ this.reportInstance.printReport(); }, /* * oncick event responsible for handling the toolbar's cancel button click. */ cancel: function(){ this.reportInstance.cancelReport(); }, /* * oncick event responsible for handling the toolbar's export button click. */ performExport: function(){ exportSelect = document.getElementById(this.buildUniqueString('ddCmbExport')); if(exportSelect !=null){ value = exportSelect.value; if(value != 'SelectFormat'){ DiagContext.traceVerbose('exporting report ' + value); this.reportInstance.exportReport(value); } } }, /* * oncick event responsible for handling the toolbar's DocumentMap show/hide button click. */ toggleDocMap: function(){ var docPanelControl = document.getElementById(this.buildUniqueString('documentMapArea')); if(docPanelControl!=null){ docPanelControl = docPanelControl.parentNode.parentNode; display = (docPanelControl.style.display=='')?'none':''; this._setDocMapDisplay(display); } }, /* * Onclick event to toggle the side bar when using the report viewer composite control. */ toggleSideBar: function(){ var sideBar = document.getElementById(this.buildUniqueString('reportViewerSideBar')); if(sideBar == null) return; var sideBarId = "#"+sideBar.id.replace(/\$/g, "\\$"); if(sideBar.style.display.length==0){ sideBar.style.display = 'none'; jQuery(sideBarId).removeClass('visibleSideBar sidebar').addClass('hiddenSideBar'); } else{ sideBar.style.display=''; jQuery(sideBarId).removeClass('hiddenSideBar sidebar').addClass('visibleSideBar'); } initializeSize(); }, _showSideBar: function(){ var sideBar = document.getElementById(this.buildUniqueString('reportViewerSideBar')); if(sideBar == null) return; sideBar.style.display = ''; initializeSize(); }, _hideSideBar: function(){ var sideBar = document.getElementById(this.buildUniqueString('reportViewerSideBar')); if(sideBar == null) return; sideBar.style.display = 'none'; initializeSize(); }, /* * Shows the document map side bar panel and hides the find panel. */ showDocMapSideBar: function(){ var docMapSideBar = document.getElementById(this.buildUniqueString('reportViewerDocumentMapSideBar')); if(docMapSideBar.style.display.length==0) return; var findSideBar = document.getElementById(this.buildUniqueString('reportViewerFindSideBar')); if(findSideBar!=null){ this.performingFind = false; findSideBar.style.display = 'none'; } var paramSideBar = document.getElementById(this.buildUniqueString('reportViewerParameterSideBar')); if(paramSideBar != null){ paramSideBar.style.display = 'none'; } docMapSideBar.style.display = ''; }, /* * Shows the find side bar panel and hides the DocMap panel. */ showFindSideBar: function(){ var findSideBar = document.getElementById(this.buildUniqueString('reportViewerFindSideBar')); if(findSideBar.style.display.length==0) return; var docMapSideBar = document.getElementById(this.buildUniqueString('reportViewerDocumentMapSideBar')); if(docMapSideBar!=null) docMapSideBar.style.display = 'none'; var paramSideBar = document.getElementById(this.buildUniqueString('reportViewerParameterSideBar')); if(paramSideBar != null){ paramSideBar.style.display = 'none'; } findSideBar.style.display = ''; }, /* * Onclick event to toggle the parameter panel when using the report viewer composite control. */ showParameterSideBar: function(){ var paramSideBar = document.getElementById(this.buildUniqueString('reportViewerParameterSideBar')); if(paramSideBar.style.display.length == 0){ return; } var docMapSideBar = document.getElementById(this.buildUniqueString('reportViewerDocumentMapSideBar')); if(docMapSideBar!=null){ docMapSideBar.style.display = 'none'; } var findSideBar = document.getElementById(this.buildUniqueString('reportViewerFindSideBar')); if(findSideBar!=null){ findSideBar.style.display = 'none'; this.performingFind = false; } paramSideBar.style.display = ''; }, /* * Onclick event to change the viewer mode to/from HTML and PDF. */ setViewerMode: function(){ DiagContext.traceVerbose('setting viewer mode'); var viewerModeSelect = document.getElementById(this.buildUniqueString('ddCmbViewerMode')); if(viewerModeSelect != null){ if(viewerModeSelect.selectedIndex > 0){ value = viewerModeSelect.value; DiagContext.traceVerbose('changing viewer mode to ' + value); this.reportInstance.changeViewerMode(value); } } }, /* * Sets the display of the document map panel control to the toggle value. * Parameter: toggle is the display value to set the document map panel control to; value should be either '' or 'none' */ _setDocMapDisplay: function(toggle){ docPanelControl = document.getElementById(this.buildUniqueString('documentMapArea')); if(docPanelControl!=null){ docPanelControl = docPanelControl.parentNode.parentNode; docPanelControl.style.display = toggle; } }, /* * onchange event responsible for handling the toolbar's viewer mode selection change event */ viewerModeChanged: function(evt){ if(evt == null){ evt = window.event; } var owner = evt.target; if(owner == null){ owner = evt.srcElement; } DiagContext.traceVerbose('viewerModeChanged ' + owner.selectedIndex + ' ' + owner.value); if(owner.selectedIndex == 0){ return; } else{ viewerModeButton = document.getElementById(this.buildUniqueString('ddBtnViewerMode')); if(viewerModeButton !=null){ if(owner.value != this.reportInstance.format){ enable(viewerModeButton); } else{ disable(viewerModeButton); } } } }, /* * onchange event responsible for handling the toolbar's zoom selection change event. */ zoomChanged: function(evt){ if (evt == null){ evt = window.event; } var owner = evt.target; if (owner == null) owner = evt.srcElement; alert('Zoom level ' + owner.value + ' Not Implemented'); }, /* * oncick event responsible for handling the toggeling of a section in the core viewer panel */ toggleSection: function(lpath){ DiagContext.traceVerbose('toggleSection fired for path ' + lpath); this.reportInstance.toggle(lpath); }, /* * onclick event responsible for initating a find on a search string in a report. */ findText: function(evt){ var searchInput = document.getElementById(this.buildUniqueString('tbFindText')); var chkWholeWord = document.getElementById(this.buildUniqueString('chkFindWholeWord')); var chkMatchCase = document.getElementById(this.buildUniqueString('chkMatchCase')); var advancedSearchOption = ''; if(this._isAdvancedSearchMode()){ var advancedSearchSelect = document.getElementById(this.buildUniqueString('cmbAdvancedOptions')); advancedSearchOption = advancedSearchSelect.value; } if(searchInput !=null){ var value = searchInput.value; if(value.length>0){ var findPanel = document.getElementById('FindResultPanelRepViewer$coreViewer'); findPanel.innerHTML = ''; this.performingFind = true; this.reportInstance.findText(value, chkWholeWord.checked, chkMatchCase.checked, advancedSearchOption); } } }, /* * Resets the find panel to the default state. */ clearFindPanel: function(evt){ var searchInput = document.getElementById(this.buildUniqueString('tbFindText')); searchInput.value = ''; var chkWholeWord = document.getElementById(this.buildUniqueString('chkFindWholeWord')); chkWholeWord.checked = false; var chkMatchCase = document.getElementById(this.buildUniqueString('chkMatchCase')); chkMatchCase.checked = false; if(this._isAdvancedSearchMode()){ this.toggleSearchOptions(); } var findResultsPanel = document.getElementById(this.buildUniqueString('FindResultPanel')); findResultsPanel.innerHTML = ''; }, /* * onclick event responsible for toggeling the advanced/basic search options on the find panel */ toggleSearchOptions: function(evt){ var advancedOptionsCaption = document.getElementById(this.buildUniqueString('advancedSearchOptionsCaption')); var basicOptionCaption = document.getElementById(this.buildUniqueString('basicSearchOptionsCaption')); var optionsSection = document.getElementById(this.buildUniqueString('advancedSearchOptions')); if(this._isAdvancedSearchMode()){ //switch to basic mode advancedOptionsCaption.style.display = ''; basicOptionCaption.style.display = 'none'; optionsSection.style.display = 'none'; } else{ //switch to advanced mode advancedOptionsCaption.style.display = 'none'; basicOptionCaption.style.display = ''; optionsSection.style.display = ''; } }, /* * Indicates if the find panel is currently being displayed with the advanced search options. */ _isAdvancedSearchMode: function(){ var optionsSection = document.getElementById(this.buildUniqueString('advancedSearchOptions')); return (optionsSection.style.display.length == 0); }, /* * onblur event responsible for handling the onblur event of text input parameter controls. It * updates the parameters collection with the new value. */ parameterBlur: function(evt){ if (evt == null) evt = window.event; var owner = evt.target; if (owner == null) owner = evt.srcElement; controllerRepViewer$coreViewer.validateInput(owner); }, /* * Shows the Calendar control popup */ showCalendarPopup: function(evt){ if (evt == null) evt = window.event; var owner = evt.target; if (owner == null) owner = evt.srcElement; var datepickerInputId = owner.id.replace('TriggerImage', ''); var datepickerInput = document.getElementById(datepickerInputId); if(datepickerInput != null && datepickerInput.disabled) return; var datepickerId = datepickerInputId.replace(/\$/g, "\\$"); jQuery("#"+datepickerId).datepicker("show"); }, /* * Performs validation on the input control's value to ensure it's valid for the parameter type. */ validateInput: function(target){ var control = target;//document.getElementById(target.id); if(control.nodeName == "INPUT" || control.nodeName == "TEXTAREA"){ var parameterIndex = this._getParameterIndexFromId(control.id); parameter = this.reportInstance.parameters.getParameter(parameterIndex); if(parameter.multiValue){ var valuesSplit = control.value.split(','); parameter.values.clear(); for(var i=0;i 0){ this._refreshParameter(parameter); } } else if((control.value != parameter.value && defaultValue.length == 0) || (defaultValue != control.value) ){ var isValidValue = this._validateParameterValue(parameter, control.value, false, 'valMessage' + control.id); if(!isValidValue){ return; } parameter.value = control.value; this._refreshParameter(parameter); } return; } if(control.nodeName == "INPUT"){ var parameterIndex = this._getParameterIndexFromId(control.id); parameter = this.reportInstance.parameters.getParameter(parameterIndex); var value = control.value; var isValidValue = this._validateParameterValue(parameter, value, false, 'valMessage' + control.id); if(isValidValue){ if(parameter.defaultValue!=null){ defaultValue = (parameter.defaultValue[0]==null)?'':parameter.defaultValue[0].value; } if(parameter.dataType == 'DateTime' && !parameter.dateOnly){ var idForParameterInput = this._getParameterIdFromIndex(parameterIndex); dateControl = document.getElementById(idForParameterInput); timeControl = document.getElementById("Time"+idForParameterInput); dateTimeControlValue = dateControl.value + " " + timeControl.value; if(parameter.value != dateTimeControlValue && defaultValue != dateTimeControlValue){ parameter.value = dateTimeControlValue; this._refreshParameter(parameter); } } else{ if(parameter.value != value && defaultValue != control.value){ parameter.value = value; this._refreshParameter(parameter); } } } return; } }, /* * Performs basic validation on a parameter value. * Parameters: parameter, the parameter being changed. newValue: the value of the html control being validated. IsNull: indiacate if the null checkbox has been selected or not. */ _validateParameterValue: function(parameter, newValue, isNull, messageDivId){ var isParameterValid = true; var validationMessage = ""; newValue = newValue.replace(/^\s+|\s+$/, ''); //trim out the whitespace incase it's empty spaces if(!isNull){ if(parameter.dataType == 'String'){ if(!parameter.allowBlank && (newValue.length == 0)){ isParameterValid = false; validationMessage = this.resources.getBlankValueNotSupportedMessage(); } else{ isParameterValid = true; } } else if(parameter.dataType == 'Integer'){ var result = parseInt(newValue); if(parameter.allowBlank && newValue.length == 0){ isParameterValid = true; } else if(isNaN(result)){ isParameterValid = false validationMessage = this.resources.getInvalidIntegerParameterValueMessage(); } else if(result != newValue){ isParameterValid = false; validationMessage = this.resources.getInvalidIntegerParameterValueMessage(); } else{ isParameterValid = true; } } else if(parameter.dataType == 'Float'){ if(!parameter.allowBlank && (newValue.length == 0)){ isParameterValid = false; validationMessage = this.resources.getBlankValueNotSupportedMessage(); } else{ isParameterValid = true; } // Case 36724 - validate float values on server-side using report language/server regional settings. } else if(parameter.dataType == 'DateTime'){ /* CR25802: we should perform validation on server side according to regional settings */ isParameterValid = true; } } var selectionControl = parameter.definesValidValues; // if the condition below is true then