Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSRS Report Manager javascript fails in non-IE browsers for Drop Down Menus

I've been debugging the ReportingServices.js file using Firefox and Firebug. I've found that the reason SSRS (SQL Server Reporting Services) Report Manager (web front end for Reports) doesn't work in Firefox (v7.0.1) is that it's using javascript .lastChild to find elements. Unfortunately, Firefox also picks up on whitespace as TextNode elements causing the element selection to not work as expected.

This works in IE and hopefully someone knows a solution to this. I edited the javascript to get round one bug but then hit another more complicated one so probably a mine field to try to fix manually. Hopefully there is some update or patch available.

This is running SQL Server 2008 R2 Standard edition on a Windows 2008 R2 Datacenter server.

Apologies if you feel this is not the forum for such a question. In that case, please suggest where else I should ask the question if it's not appropriate. It is kindof a javascript problem but likely with a software update solution.

Updated:

After a few hours of fixing the browser compatibility bugs in the ReportingServices.js file I managed to get it to work on Firefox, Chrome, Opera and Safari as well as IE. Sorry that my answer below is in 2 parts; I posted the entire code of the updated ReportingServices.js for the solution.

like image 577
Chris Snowden Avatar asked Oct 20 '11 14:10

Chris Snowden


People also ask

Can not open the drop down arrow besides the report in SSRS?

This drop-down issue is an issue with the compatibility setting. Go to: Tools/Compatibility View Settings and enter "localhost" and/or whatever your is (do both). "Fixes" things up.

Does SSRS work in Edge?

Yes. The default authentication settings work with Edge.

Does Microsoft still support SSRS?

SQL Server 2016 Reporting Services or later (SSRS) supports the current versions of Microsoft . NET Framework 4, including version 4.0 and 4.5.

How do I configure Reporting Services Configuration Manager?

To start the Report Server Configuration ManagerIn the Windows start menu, type reporting and in the Apps search results, click Report Server Configuration Manager. Click Start, then click Programs, then click Microsoft SQL Server, then click Configuration Tools, and then click Report Server Configuration Manager.


1 Answers

After a few hours hacking around with the original ReportingServices.js file I managed to fix the javascript to work on Firefox, Chrome, Opera and Safari as well as IE.

Even though it's a bit big I've posted the whole edited ReportingServices.js 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.

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.

I had to post it in 2 parts. Hope this helps others!

/*
    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 && child.isElementContentWhitespace) {
        child = child.nextSibling;
    }
    return child;
}

function lastChildNoWS(element) {
    var child = element.lastChild;
    while (child != null && 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 && !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 && !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 < checkBoxCount; i++) {
        id = checkBoxId + i;
        document.getElementById(id).checked = checked;
    }
}

/// onSglCheck
/// performs actions when a single checkBox is checked or unchecked
/// cb -> the checkBox generating the event
/// topId -> 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 -> id prefix of the checkBoxes
/// cbCount -> total checkBoxes to check
/// hidden -> input to look for
/// display -> control to disable
function CheckCheckBoxes(cbid, hidden, display) {
    var i;
    var id;
    var disable;

    disable = false;
    for (i = 0; i < 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 < 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 < 10 && val >= 0) {
        if (s.length == 1)
            s = "0" + s;
        else if (s.length > 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 > 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 >= 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 < checkBoxCount && checkedCount < 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 && headerCheckBox.checked) {
        enableMultiButtons = true;
        multipleCheckboxesSelected = checkBoxCount > 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 < 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 < 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 && storedRadioButton.checked) {
        /*      if (shadowField.value.length > 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 && !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 > 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 && 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 < valueArray.length; i++) {
            // If the string is non-blank, add it
            if (valueArray[i].length > 0) {
                if (finalValue.length > 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 > 1)
        startIndex = 1;

    for (var i = startIndex; i < 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 > 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 < 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 > 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 > 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();
}
like image 118
Chris Snowden Avatar answered Sep 17 '22 16:09

Chris Snowden