Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>After a few hours hacking around with the original <code>ReportingServices.js</code> file I managed to fix the javascript to work on Firefox, Chrome, Opera and Safari as well as IE.</p> <p>Even though it's a bit big I've posted the whole edited <code>ReportingServices.js</code> below for others to use if needed. I've put "chris edit" comments showing the old lines above their edits so you can (if you care) follow what I've changed. I've also summarized these changes at the top of the code.</p> <p>The SSRS report manager web interface is very useful and it would be a shame not to use it just because Microsoft didn't bother to test it on other browsers than IE. This is why I always prefer jQuery over plain javascript to avoid these kind of cross browser compatibility issues.</p> <p>I had to post it in 2 parts. Hope this helps others!</p> <pre><code>/* Author: Chris Snowden Modified Date: 21st October 2011 ReportingServices.js file for SQL Server 2008 R2 Reporting Services Updated to fix a bug whereby drop down context menus didn't work for any other browser than IE. 1) I added functions to find firstChild and lastChild while skipping any whitespace TextNode elements. 2) I updated the Clicked function to get at the table element value in a way that works for firefox. 3) I updated the SplitContextMenuConfigString function to access the table cells by first looping through each row and then the cells. Drop downs now work on Firefox, Chrome, Opera and Safari as well as IE. */ var checkBoxCount; var checkBoxId; var checkBoxHead; // Context menu var _divContextMenu; // The container for the context menu var _selectedIdHiddenField; // The id of the item that opened th context menu var _timeOutLimit = 3000; // How long the context menu stays for after the cursor in no longer over it var _timeOutTimer; // The timout for the context menu var _itemSelected = false; var _mouseOverContext = false; // If the mouse is over the context menu var _contextMenusIds; // The array of the diffrent context menus var _fadeTimeouts; // The array of timouts used for the fade effect var _onLink = false; // If the user is over a name link var _selectedItemId; var _tabFocusedItem = ''; var _mouseOverItem = ''; var _unselectedItemStyle; var _currentContextMenuId; // ID of currently displayed context menu var _currentMenuItemId = null; // ID of currently selected context menu item // Search bar var _searchTextBoxID; var _defaultSearchValue; // The value that the box defaults to. // start chris edit // new functions to find firstChild and lastChild but skipping whitespace elements function firstChildNoWS(element) { var child = element.firstChild; while (child != null &amp;&amp; child.isElementContentWhitespace) { child = child.nextSibling; } return child; } function lastChildNoWS(element) { var child = element.lastChild; while (child != null &amp;&amp; child.isElementContentWhitespace) { child = child.previousSibling; } return child; } // end chris edit function ToggleItem(itemId) { var item = document.getElementById(itemId); if (item.style.display == 'none') item.style.display = 'inline'; else item.style.display = 'none'; } function ToggleButtonImage(image1ID, image2ID) { var image1 = document.getElementById(image1ID); var image2 = document.getElementById(image2ID); if (image1.style.display == 'none') { image1.style.display = 'inline-block'; image2.style.display = 'none'; } else { image1.style.display = 'none'; image2.style.display = 'inline-block'; } } function SetFocus(id) { var obj = document.getElementById(id); if (obj != null &amp;&amp; !obj.disabled) obj.focus(); } // Validates that an extension has been selected function ValidateDropDownSelection(source, args) { var obj = document.getElementById(source.controltovalidate); if (obj.options[0].selected &amp;&amp; !obj.disabled) args.IsValid = false; else args.IsValid = true; } /// selectAll /// selects all the checkBoxes with the given id function selectAll() { var i; var id; var checked = checkBoxHead.checked; for (i = 0; i &lt; checkBoxCount; i++) { id = checkBoxId + i; document.getElementById(id).checked = checked; } } /// onSglCheck /// performs actions when a single checkBox is checked or unchecked /// cb -&gt; the checkBox generating the event /// topId -&gt; id of the "select all" checkBox function onSglCheck() { // uncheck the top checkBox checkBoxHead.checked = false; } /// ToggleButton /// Toggle a buttons enable state function ToggleButton(id, disabled) { if (document.getElementById(id) != null) document.getElementById(id).disabled = disabled; } function ToggleValidator(id, enabled) { document.getElementById(id).enabled = enabled; } function SetCbVars(cbid, count, cbh) { checkBoxCount = count; checkBoxId = cbid; checkBoxHead = cbh; } /// Check to see if any check boxes should disable /// a control /// cbid -&gt; id prefix of the checkBoxes /// cbCount -&gt; total checkBoxes to check /// hidden -&gt; input to look for /// display -&gt; control to disable function CheckCheckBoxes(cbid, hidden, display) { var i; var id; var disable; disable = false; for (i = 0; i &lt; checkBoxCount; i++) { id = cbid + i; if (document.getElementById(id).checked) { id = hidden + id; if (document.getElementById(id) != null) { disable = true; break; } } } ToggleButton(display, disable); } function HiddenCheckClickHandler(hiddenID, promptID, promptStringID) { var hiddenChk = document.getElementById(hiddenID); var promptChk = document.getElementById(promptID); // prompt should be in opposite state of hidden promptChk.checked = !hiddenChk.checked; } function validateSaveRole(source, args) { var i; var id; var c = 0; for (i = 0; i &lt; checkBoxCount; i++) { id = checkBoxId + i; if (document.getElementById(id).checked) c++; } if (0 == c) args.IsValid = false; else args.IsValid = true; } /// Pad an integer less then 10 with a leading zero function PadIntWithZero(val) { var s = val.toString(); if (val &lt; 10 &amp;&amp; val &gt;= 0) { if (s.length == 1) s = "0" + s; else if (s.length &gt; 2) s = s.substring(s.length - 2, s.length); } return s; } /// Pad the contents of an input with leading zeros if necesarry function PadInputInteger(id) { document.getElementById(id).value = PadIntWithZero(document.getElementById(id).value); } /// text of confirmation popup when a single item is selected for deletion /// e.g. "Are you sure you want to delete this item" var confirmSingle; /// text of confirmation popup when multiple items are selected for deletion /// e.g. "Are you sure you want to delete these items" var confirmMultiple; function SetDeleteTxt(single, multiple) { confirmSingle = single; confirmMultiple = multiple; } /// doCmDel: DoConfirmDelete /// Given a number of checked items, confirm their deletion /// return true if OK was clicked; false otherwise function doCmDel(checkedCount) { var confirmTxt = confirmSingle; if (checkedCount == 0) return false; if (checkedCount &gt; 1) confirmTxt = confirmMultiple; return confirm(confirmTxt); } /// on non-Netscape browsers, confirm deletion of 0 or more items function confirmDelete() { return doCmDel(getChkCount()); } /// confirm deletion of policies function confirmDeletePlcies(alertString) { var count = getChkCount(); if (count &gt;= checkBoxCount) { alert(alertString); return false; } return doCmDel(count); } /// counts whether 0, 1, or more than 1 checkboxes are checked /// returns 0, 1, or 2 function getChkCount() { var checkedCount = 0; for (i = 0; i &lt; checkBoxCount &amp;&amp; checkedCount &lt; 2; i++) { if (document.getElementById(checkBoxId + i).checked) { checkedCount++; } } return checkedCount; } function ToggleButtonBasedOnCheckBox(checkBoxId, toggleId, reverse) { var chkb = document.getElementById(checkBoxId); if (chkb != null) { if (chkb.checked == true) ToggleButton(toggleId, reverse); // enable if reverse == false else ToggleButton(toggleId, !reverse); // disable if reverse == false } } function ToggleButtonBasedOnCheckBoxWithOverride(checkBoxId, toggleId, overrideToDisabled, reverse) { if (overrideToDisabled == true) ToggleButton(toggleId, true); // disable else ToggleButtonBasedOnCheckBox(checkBoxId, toggleId, reverse); } function ToggleButtonBasedOnCheckBoxes(checkBoxId, checkboxId2, toggleId) { var chkb = document.getElementById(checkBoxId); if (chkb != null) { if (chkb.checked == true) ToggleButtonBasedOnCheckBox(checkboxId2, toggleId, false); else ToggleButton(toggleId, true); // disable } } function ToggleButtonBasedOnCheckBoxesWithOverride(checkBoxId, checkboxId2, toggleId, overrideToDisabled) { if (overrideToDisabled == true) ToggleButton(toggleId, true); // disable else ToggleButtonBasedOnCheckBoxes(checkBoxId, checkboxId2, toggleId); } function ToggleValidatorBasedOnCheckBoxWithOverride(checkBoxId, toggleId, overrideToDisabled, reverse) { if (overrideToDisabled == true) ToggleValidator(toggleId, false); else { var chkb = document.getElementById(checkBoxId); if (chkb != null) { ToggleValidator(toggleId, chkb.checked != reverse); } } } function ToggleValidatorBasedOnCheckBoxesWithOverride(checkBoxId, checkBoxId2, toggleId, overrideToDisabled, reverse) { if (overrideToDisabled == true) ToggleValidator(toggleId, false); else { var chkb = document.getElementById(checkBoxId); if (chkb != null) { if (chkb.checked == reverse) ToggleValidator(toggleId, false); else ToggleValidatorBasedOnCheckBoxWithOverride(checkBoxId2, toggleId, overrideToDisabled, reverse); } } } function CheckButton(buttonID, shouldCheck) { document.getElementById(buttonID).checked = shouldCheck; } function EnableMultiButtons(prefix) { // If there are no multibuttons, there is no reason to iterate the // list of checkboxes. if (checkBoxCount == 0 || multiButtonList.length == 0) return; var enableMultiButtons = false; var multipleCheckboxesSelected = false; // If the top level check box is checked, we know the state of all // of the checkboxes var headerCheckBox = document.getElementById(prefix + "ch"); if (headerCheckBox != null &amp;&amp; headerCheckBox.checked) { enableMultiButtons = true; multipleCheckboxesSelected = checkBoxCount &gt; 1; } else { // Look at each checkbox. If any one of them is checked, // enable the multi buttons. var foundOneChecked = false; var i; for (i = 0; i &lt; checkBoxCount; i++) { var checkBox = document.getElementById(prefix + 'cb' + i); if (checkBox.checked) { if (foundOneChecked) { multipleCheckboxesSelected = true; break; } else { enableMultiButtons = true; foundOneChecked = true; } } } } // Enable/disable each of the multi buttons var j; for (j = 0; j &lt; multiButtonList.length; j++) { var button = document.getElementById(multiButtonList[j]); if (button.allowMultiSelect) button.disabled = !enableMultiButtons; else button.disabled = !enableMultiButtons || multipleCheckboxesSelected; } } //function ShadowCopyPassword(suffix) function MarkPasswordFieldChanged(suffix) { if (event.propertyName == "value") { var pwdField = document.getElementById("ui_txtStoredPwd" + suffix); //var shadowField = document.getElementById("ui_shadowPassword" + suffix); var shadowChanged = document.getElementById("ui_shadowPasswordChanged" + suffix); // Don't shadow copy during initialization if (pwdField.IsInit) { //shadowField.value = pwdField.value; //pwdField.UserEnteredPassword = "true"; shadowChanged.value = "true"; // Update validator state (there is no validator on the data driven subscription page) var validator = document.getElementById("ui_validatorPassword" + suffix) if (validator != null) ValidatorValidate(validator); } } } function InitDataSourcePassword(suffix) { var pwdField = document.getElementById("ui_txtStoredPwd" + suffix); var shadowChanged = document.getElementById("ui_shadowPasswordChanged" + suffix); // var shadowField = document.getElementById("ui_shadowPassword" + suffix); var storedRadioButton = document.getElementById("ui_rdoStored" + suffix); var pwdValidator = document.getElementById("ui_validatorPassword" + suffix); pwdField.IsInit = false; // Initialize the field to the shadow value (for when the user clicks back/forward) // Or to a junk initial value. if (pwdValidator != null &amp;&amp; storedRadioButton.checked) { /* if (shadowField.value.length &gt; 0) pwdField.value = shadowField.value; else*/ pwdField.value = "********"; } else shadowChanged.value = "true"; // shadowChanged will be ignored if the page is submitted without storedRadioButton.checked // Now that the initial value is set, track changes to the password field pwdField.IsInit = true; // There is no validator on the data driven subscription page (no stored radio button either) if (pwdValidator != null) ValidatorValidate(pwdValidator); } function SetNeedPassword(suffix) { // Set a flag indicating that we need the password var pwdField = document.getElementById("ui_txtStoredPwd" + suffix); pwdField.NeedPassword = "true"; // Make the validator visible ValidatorValidate(document.getElementById("ui_validatorPassword" + suffix)); } function UpdateValidator(src, validatorID) { if (src.checked) { var validator = document.getElementById(validatorID); ValidatorValidate(validator); } } function ReEnterPasswordValidation(source, arguments) // source = validator { var validatorIdPrefix = "ui_validatorPassword" var suffix = source.id.substr(validatorIdPrefix.length, source.id.length - validatorIdPrefix.length); var storedRadioButton = document.getElementById("ui_rdoStored" + suffix); var pwdField = document.getElementById("ui_txtStoredPwd" + suffix); var shadowChanged = document.getElementById("ui_shadowPasswordChanged" + suffix); var customDataSourceRadioButton = document.getElementById("ui_rdoCustomDataSource" + suffix); var isCustomSelected = true; if (customDataSourceRadioButton != null) isCustomSelected = customDataSourceRadioButton.checked; if (!isCustomSelected || // If the custom (vs shared) data source radio button exists and is not selected, we don't need the pwd. storedRadioButton.checked == false || // If the data source is not using stored credentials, we don't need the password pwdField.UserEnteredPassword == "true" || // If the password has changed, we don't need to get it from the user pwdField.NeedPassword != "true" || // If no credentials have changed, we don't need the password shadowChanged.value == "true") // If the user has typed a password arguments.IsValid = true; else arguments.IsValid = false; } function ValidateDataSourceSelected(source, arguments) { var validatorIdPrefix = "ui_sharedDSSelectedValidator" var suffix = source.id.substr(validatorIdPrefix.length, source.id.length - validatorIdPrefix.length); var sharedRadioButton = document.getElementById("ui_rdoSharedDataSource" + suffix); var hiddenField = document.getElementById("ui_hiddenSharedDS" + suffix); arguments.IsValid = (sharedRadioButton != null &amp;&amp; !sharedRadioButton.checked) || hiddenField.value != "NotSelected"; } /**************************************************************************/ // MultiValueParamClass function MultiValueParamClass(thisID, visibleTextBoxID, floatingEditorID, floatingIFrameID, paramObject, hasValidValues, allowBlank, doPostbackOnHide, postbackScript) { this.m_thisID = thisID; this.m_visibleTextBoxID = visibleTextBoxID; this.m_floatingEditorID = floatingEditorID; this.m_floatingIFrameID = floatingIFrameID; this.m_paramObject = paramObject; this.m_hasValidValues = hasValidValues; this.m_allowBlank = allowBlank; this.m_doPostbackOnHide = doPostbackOnHide; this.m_postbackScript = postbackScript; this.UpdateSummaryString(); } function ToggleVisibility() { var floatingEditor = GetControl(this.m_floatingEditorID); if (floatingEditor.style.display != "inline") this.Show(); else this.Hide(); } MultiValueParamClass.prototype.ToggleVisibility = ToggleVisibility; function Show() { var floatingEditor = GetControl(this.m_floatingEditorID); if (floatingEditor.style.display == "inline") return; // Set the correct size of the floating editor - no more than // 150 pixels high and no less than the width of the text box var visibleTextBox = GetControl(this.m_visibleTextBoxID); if (this.m_hasValidValues) { if (floatingEditor.offsetHeight &gt; 150) floatingEditor.style.height = 150; floatingEditor.style.width = visibleTextBox.offsetWidth; } var newEditorPosition = this.GetNewFloatingEditorPosition(); floatingEditor.style.left = newEditorPosition.Left; floatingEditor.style.top = newEditorPosition.Top; floatingEditor.style.display = "inline"; var floatingIFrame = GetControl(this.m_floatingIFrameID); floatingIFrame.style.left = floatingEditor.style.left; floatingIFrame.style.top = floatingEditor.style.top; floatingIFrame.style.width = floatingEditor.offsetWidth; floatingIFrame.style.height = floatingEditor.offsetHeight; floatingIFrame.style.display = "inline"; // If another multi value is open, close it first if (this.m_paramObject.ActiveMultValue != this &amp;&amp; this.m_paramObject.ActiveMultiValue != null) ControlClicked(this.m_paramObject.id); this.m_paramObject.ActiveMultiValue = this; if (floatingEditor.childNodes[0].focus) floatingEditor.childNodes[0].focus(); this.StartPolling(); } MultiValueParamClass.prototype.Show = Show; function Hide() { var floatingEditor = GetControl(this.m_floatingEditorID); var floatingIFrame = GetControl(this.m_floatingIFrameID); // Hide the editor floatingEditor.style.display = "none"; floatingIFrame.style.display = "none"; this.UpdateSummaryString(); if (this.m_doPostbackOnHide) eval(this.m_postbackScript); // Check that the reference is still us in case event ordering // caused another multivalue to click open if (this.m_paramObject.ActiveMultiValue == this) this.m_paramObject.ActiveMultiValue = null; } MultiValueParamClass.prototype.Hide = Hide; function GetNewFloatingEditorPosition() { // Make the editor visible var visibleTextBox = GetControl(this.m_visibleTextBoxID); var textBoxPosition = GetObjectPosition(visibleTextBox); return { Left: textBoxPosition.Left, Top: textBoxPosition.Top + visibleTextBox.offsetHeight }; } MultiValueParamClass.prototype.GetNewFloatingEditorPosition = GetNewFloatingEditorPosition; function UpdateSummaryString() { var summaryString; if (this.m_hasValidValues) summaryString = GetValueStringFromValidValueList(this.m_floatingEditorID); else summaryString = GetValueStringFromTextEditor(this.m_floatingEditorID, false, this.m_allowBlank); var visibleTextBox = GetControl(this.m_visibleTextBoxID); visibleTextBox.value = summaryString; } MultiValueParamClass.prototype.UpdateSummaryString = UpdateSummaryString; function StartPolling() { setTimeout(this.m_thisID + ".PollingCallback();", 100); } MultiValueParamClass.prototype.StartPolling = StartPolling; function PollingCallback() { // If the editor isn't visible, no more events. var floatingEditor = GetControl(this.m_floatingEditorID); if (floatingEditor.style.display != "inline") return; // If the text box moved, something on the page resized, so close the editor var expectedEditorPos = this.GetNewFloatingEditorPosition(); if (floatingEditor.style.left != expectedEditorPos.Left + "px" || floatingEditor.style.top != expectedEditorPos.Top + "px") { this.Hide(); } else { this.StartPolling(); } } MultiValueParamClass.prototype.PollingCallback = PollingCallback; /*****************************************************************************/ function GetObjectPosition(obj) { var totalTop = 0; var totalLeft = 0; while (obj != document.body) { // Add up the position totalTop += obj.offsetTop; totalLeft += obj.offsetLeft; // Prepare for next iteration obj = obj.offsetParent; } totalTop += obj.offsetTop; totalLeft += obj.offsetLeft; return { Left: totalLeft, Top: totalTop }; } function GetValueStringFromTextEditor(floatingEditorID, asRaw, allowBlank) { var span = GetControl(floatingEditorID); var editor = span.childNodes[0]; var valueString = editor.value; // Remove the blanks if (!allowBlank) { // Break down the text box string to the individual lines var valueArray = valueString.split("\r\n"); var delimiter; if (asRaw) delimiter = "\r\n"; else delimiter = ", "; var finalValue = ""; for (var i = 0; i &lt; valueArray.length; i++) { // If the string is non-blank, add it if (valueArray[i].length &gt; 0) { if (finalValue.length &gt; 0) finalValue += delimiter; finalValue += valueArray[i]; } } return finalValue; } else { if (asRaw) return valueString; else return valueString.replace(/\r\n/g, ", "); } } function GetValueStringFromValidValueList(editorID) { var valueString = ""; // Get the table var div = GetControl(editorID); var table = div.childNodes[0]; if (table.nodeName != "TABLE") // Skip whitespace if needed table = div.childNodes[1]; // If there is only one element, it is a real value, not the select all option var startIndex = 0; if (table.rows.length &gt; 1) startIndex = 1; for (var i = startIndex; i &lt; table.rows.length; i++) { // Get the first cell of the row var firstCell = table.rows[i].cells[0]; var span = firstCell.childNodes[0]; var checkBox = span.childNodes[0]; var label = span.childNodes[1]; if (checkBox.checked) { if (valueString.length &gt; 0) valueString += ", "; // chris edit - valueString += label.firstChild.nodeValue; valueString += firstChildNoWS(label).nodeValue; } } return valueString; } function MultiValidValuesSelectAll(src, editorID) { // Get the table var div = GetControl(editorID); var table = div.childNodes[0]; if (table.nodeName != "TABLE") table = div.childNodes[1]; for (var i = 1; i &lt; table.rows.length; i++) { // Get the first cell of the row var firstCell = table.rows[i].cells[0]; var span = firstCell.childNodes[0]; var checkBox = span.childNodes[0]; checkBox.checked = src.checked; } } function ValidateMultiValidValue(editorID, errMsg) { var summaryString = GetValueStringFromValidValueList(editorID); var isValid = summaryString.length &gt; 0; if (!isValid) alert(errMsg) return isValid; } function ValidateMultiEditValue(editorID, errMsg) { // Need to check for a value specified. This code only runs if not allow blank. // GetValueStringFromTextEditor filters out blank strings. So if it was all blank, // the final string will be length 0 var summaryString = GetValueStringFromTextEditor(editorID, true, false) var isValid = false; if (summaryString.length &gt; 0) isValid = true; if (!isValid) alert(errMsg); return isValid; } function GetControl(controlID) { var control = document.getElementById(controlID); if (control == null) alert("Unable to locate control: " + controlID); return control; } function ControlClicked(formID) { var form = GetControl(formID); if (form.ActiveMultiValue != null) form.ActiveMultiValue.Hide(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload