var submitcount = 0; function checkDisable(node) { return ((node != null) && (node.disabled != true)); } /* * Sets the focus on the first element that should "reasonably" receive it */ function Fev_FocusOnFirstFocusableFormElement() { var lFirstFocusableFormElementID; for (i = 0; i < document.forms.length; i++) { lFirstFocusableFormElementID = Fev_FocusOnDefaultElement(document.forms[i]); if (lFirstFocusableFormElementID != false) { return (lFirstFocusableFormElementID); } } return(null); } /* * Sets the focus on the first element that should "reasonably" receive it. Called from SetFocus, while previous function * called by migrated application */ function Fev_FocusOnFirstFocusableFormElement_FromSetFocus() { var lFirstFocusableFormElementID; if (document != null && document.forms != null && document.forms.length > 0) { for (i = 0; i < document.forms.length; i++) { lFirstFocusableFormElementID = Fev_FocusOnDefaultElement_FromSetFocus(document.forms[i]); if (lFirstFocusableFormElementID != false) { return (lFirstFocusableFormElementID); } } } return(null); } /* * verifies if the element inside content area, not in the header * IMPORTANT: if you modified the name of the content place holder in Application Generation Options, add it here to the list * for example '|| (objElement.id.indexOf("_MyNewPlaceHolder_") != -1) */ function IsElementInContent(objElement) { if ((objElement.id.indexOf("_PageContent_") != -1)) { return true; } else return false; } /* * Sets the focus on the first element that is able to receive it */ function Fev_FocusOnFirstFocusableElement(objForm) { if (objForm && (objForm != null)) { for (i = 0; i < objForm.length; i++) { var objElement = objForm.elements[i]; if (Fev_IsFocusableElement(objElement)) { objElement.focus(); return true; } } } return false; } /************************************************************************************** * Function : OpwnWindowCentered(URLstring) * * Description : This function is responsible to do a window .open. Open the pop up * and place it in the center of the screen. * * Parameters : URLstring. the URL for the window.open * **************************************************************************************/ function OpenWindowCentered(URLstring) { var width = 400; var height = 300; var left = parseInt((screen.availWidth/2) - (width/2)); var top = parseInt((screen.availHeight/2) - (height/2)); var windowFeatures = "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + ",resizable,scrollbars=1"; helpWindow = window.open (URLstring, "", windowFeatures); //return false; } function ISD_CopyPageSize(dropdown) { var buttonCtrl = document.getElementById(dropdown.id.replace("PageSizeSelector", "PageSizeButton")); var pageSize = "5"; if ( buttonCtrl == null ) { var buttonCtrl = document.getElementById(dropdown.id.replace("_PageSizeSelector", "PageSizeButton")); if ( buttonCtrl == null ) { return; } } if ( dropdown.selectedIndex >= 0 ) { pageSize = dropdown.options[dropdown.selectedIndex].text; } if (navigator.appName.toUpperCase().indexOf(('Microsoft').toUpperCase()) >= 0) { buttonCtrl.click(); } else { var l_newEvent = document.createEvent("MouseEvents"); l_newEvent.initEvent("click", true, true); buttonCtrl.dispatchEvent(l_newEvent); } } var ISD_OpenFilterOrLanguagePanelElement = null; var ISD_OpenFilterOrLanguageButtonElement = null; function ISD_GetPosition(oElement, propertyName) { var returnValue = 0; try { while( oElement != null ) { returnValue += eval("oElement." + propertyName); oElement = oElement.offsetParent; } } catch (e) { returnValue = 0; } return returnValue; } function ISD_HidePopupPanel() { if ( ISD_OpenFilterOrLanguagePanelElement != null && ISD_OpenFilterOrLanguagePanelElement.style.visibility == "visible" ) { ISD_OpenFilterOrLanguagePanelElement.style.visibility="hidden"; ISD_OpenFilterOrLanguagePanelElement = null; ISD_OpenFilterOrLanguageButtonElement = null; } } function ISD_HandlePopupResize() { if ( ISD_OpenFilterOrLanguagePanelElement == null ) { return; } var leftValue = ISD_GetPosition(ISD_OpenFilterOrLanguageButtonElement, "offsetLeft"); var topValue = ISD_GetPosition(ISD_OpenFilterOrLanguageButtonElement, "offsetTop"); topValue += ISD_OpenFilterOrLanguageButtonElement.offsetHeight / 2 - 3; if ( ISD_OpenFilterOrLanguageButtonElement.tagName == "A" ) { topValue += 20; leftValue += (gRTL ? -18 : 20); } else { topValue += 22; } try { if ( !gRTL ) { leftValue = leftValue - ISD_OpenFilterOrLanguagePanelElement.offsetWidth + ISD_OpenFilterOrLanguageButtonElement.offsetWidth; } } catch (e) { } if (leftValue < 0) { leftValue = 0; } ISD_OpenFilterOrLanguagePanelElement.style.left=leftValue + "px"; ISD_OpenFilterOrLanguagePanelElement.style.top=topValue + "px"; } var allowModernButtonClick = false; function ISD_ModernButtonClick(oElement,evt) { if (allowModernButtonClick) { return false; } if (evt == null) { evt = window.event; } var didIt = false; if ( evt != null ) { if ( evt.cancelBubble != null ) { evt.cancelBubble = true; didIt = true; } if ( evt.stopPropagation != null ) { evt.stopPropagation(); didIt = true; } } if ( didIt ) { allowModernButtonClick = true; oElement.childNodes[0].onclick(); return false; } else { return true; } } function ISD_ShowPopupPanel(panelName, buttonName, oElement) { if (!allowModernButtonClick) { return false; } allowModernButtonClick = false; var originalPanelName = panelName; var idx = oElement.id.indexOf(buttonName); if ( idx >= 0 ) { panelName = oElement.id.substring(0, idx) + panelName; if ( document.getElementById(panelName) == null && idx > 1 ) { panelName = oElement.id.substring(0, idx-1) + originalPanelName; } } var thePanel = document.getElementById(panelName); if ( thePanel == null ) { alert("The panel named '" + originalPanelName + "' cannot be found. It was probably deleted earlier."); return; } window.focus(); if ( thePanel.style.visibility != "visible" ) { if ( ISD_OpenFilterOrLanguagePanelElement != null ) { ISD_OpenFilterOrLanguagePanelElement.style.visibility="hidden"; } ISD_OpenFilterOrLanguagePanelElement = thePanel; ISD_OpenFilterOrLanguageButtonElement = oElement; var size1 = ISD_GetPosition(ISD_OpenFilterOrLanguagePanelElement, "offsetWidth"); thePanel.style.visibility = "hidden"; if ( typeof(thePanel.theWidth) == "undefined" ) { thePanel.theWidth = thePanel.offsetWidth - 95; } var size2 = ISD_GetPosition(ISD_OpenFilterOrLanguagePanelElement, "offsetWidth"); ISD_OpenFilterOrLanguagePanelWidth = size2 - size1; thePanel.style.visibility = "visible"; ISD_HandlePopupResize(); } else { ISD_HidePopupPanel(); } } function ISD_HandlePopupUnload() { ISD_OpenFilterOrLanguagePanelElement = null; ISD_OpenFilterOrLanguageButtonElement = null; } window.onunload = ISD_HandlePopupUnload; window.onresize = ISD_HandlePopupResize; /************************************************************************************** * Function : SubmitHRefOnce(objElement, msg) * * Description : This function should be used for the onclick HTML attribute for a * * 'a href' to ensure that the button cannot be clicked * * twice. It changes the href URL to an alert instead of the previous * * href. This href will then be reset on the postback, and the button * * will also be enabled by the postback. Note that this only works * * for an 'a href' at this time (ThemeButtons included). It is not * * tested for any of the other buttons such as ImageButton, LinkButton * * or others. * * Parameters : objElement: the button. Typically it is 'this' * * msg: The message to report when the user clicks on the button again * **************************************************************************************/ function SubmitHRefOnce(objElement, msg) { var ClientValidate = MyPage_ClientValidate(); if (ClientValidate){ submitcount += 1; } else{ submitcount = 0; return true; } var strTagName = objElement.tagName; if (strTagName != null){ strTagName = strTagName.toLowerCase(); } else{ submitcount = 0; return true; } switch (strTagName){ case "a": if (submitcount > 1) { objElement.href = 'javascript:alert("' + msg + '");'; submitcount += 1; return false; } case "input": if (submitcount > 1) { alert(msg); submitcount += 1; return false; } } return true; } function MyPage_ClientValidate(validationGroup) { Page_InvalidControlToBeFocused = null; if (typeof(Page_Validators) == "undefined") { return true; } var i; for (i = 0; i < Page_Validators.length; i++) { ValidatorValidate(Page_Validators[i], validationGroup, null); } ValidatorUpdateIsValid(); //ValidationSummaryOnSubmit(validationGroup); Page_BlockSubmit = !Page_IsValid; return Page_IsValid; } /************************************************************************************** * Function : FCKeditor_OnComplete() * * Description : Sets focus in the textarea of the FCKEditor (if the method * * Fev_FocusOnDefaultElement() determines that it appears before the * * control upon which focus would otherwise normally be set). * * Note that this method gets called upon loading of the FCKEditor in * * the page, but only AFTER Fev_FocusOnFirstFocusableFormElement() * * gets called; also, the focus needs to be set in this FCKEditor- * * provided JavaScriptAPI method because the FCKEditor does not * * respond to the conventional JavaScript focus() method. * * Parameters : pEditorInstance: reference to the FCKEditor * **************************************************************************************/ var gSetFocusOnFCKEditor = false; function FCKeditor_OnComplete(pEditorInstance) { var oEditor = pEditorInstance; if (gSetFocusOnFCKEditor == true) { oEditor.Focus(); // disable further focus setting (in case there are more than one FCKEditor textarea on page) gSetFocusOnFCKEditor = false; } } function IsVisible(objElement) { try { while( objElement != null ) { if ( typeof(objElement.className) != "undefined" && objElement.className == "popupWrapper" ) { return false; } if ( typeof(objElement.style) != "undefined" && typeof(objElement.style.visibility) != "undefined" && objElement.style.visibility == "hidden" ) { return false; } objElement = objElement.parentElement; } } catch (e) { } return true; } /* * Sets the focus on the first element that should "reasonably" receive it */ function Fev_FocusOnDefaultElement_FromSetFocus(objForm) { if (objForm && (objForm != null) && (objForm.length > 0)) { for (i = 0; i < objForm.length; i++) { var objElement = objForm.elements[i]; // if FCKEditor appears before the control upon which focus would normally be set... // (note that all FCKEditors have an component with id, "...___Config", // so that is used as the identifier) if (objElement.id.indexOf("___Config") != -1) { continue; // if you wish to include FCKEditor in the controls where focus could be set by default, // uncomment next two lines of code which indicate that focus is to be set // (later by FCKeditor_OnComplete()) on the FCKEditor: // gSetFocusOnFCKEditor = true; // return true; } // if you wish to include Header controls in the list of focusable controls comment out this check if (!IsElementInContent(objElement)) continue; if (Fev_IsFocusableElement(objElement)) { var strType = Fev_GetElementType(objElement); if ( objElement.className.indexOf("Pagination_Input") == 0 ) { continue; } if ( objElement.className.indexOf("Search_Input") == 0 && objElement.outerHTML.indexOf("Search_InputHint") > 0 ) { continue; } if ( !IsVisible(objElement) ) { continue; } //we know (strType != null) because it was checked within Fev_IsFocusableElement(). //NOTE: SELECT tags interfere with mousewheel scrolling when they have focus // NOTE: if you want to ignore 'select' tags (dropdown list for example) you have to uncomment // the following code: // if (strType.toLowerCase().indexOf("select") == 0) // { // // } // else // { // if object and all it's parents are visible... if (Fev_IsElementVisible(objElement)) { // if the FCKEditor does not appear before the control upon which focus would normally be set... if (gSetFocusOnFCKEditor == false) { // sam - Bug 84611 - don't set focus here (focus will be set by Kirill's FixFocus.js code); just return id of focusable control // just set focus on the "normal" control // objElement.focus(); // return true; return objElement.id; } // } closing tag for ignore 'select' tag } } } } return false; } /* * Sets the focus on the first element that should "reasonably" receive it */ function Fev_FocusOnDefaultElement(objForm) { if (objForm && (objForm != null)) { for (i = 0; i < objForm.length; i++) { var objElement = objForm.elements[i]; // if FCKEditor appears before the control upon which focus would normally be set... // (note that all FCKEditors have an component with id, "...___Config", // so that is used as the identifier) if (objElement.id.indexOf("___Config") != -1) { continue; // if you wish to include FCKEditor in the controls where focus could be set by default, // uncomment next two lines of code which indicate that focus is to be set // (later by FCKeditor_OnComplete()) on the FCKEditor: // gSetFocusOnFCKEditor = true; // return true; } if (Fev_IsFocusableElement(objElement)) { var strType = Fev_GetElementType(objElement); //we know (strType != null) because it was checked within Fev_IsFocusableElement(). if (strType.toLowerCase().indexOf("select") == 0) { //NOTE: SELECT tags are ignored (they interfere with mousewheel scrolling when they have focus) } else { // if object and all it's parents are visible... if (Fev_IsElementVisible(objElement)) { // if the FCKEditor does not appear before the control upon which focus would normally be set... if (gSetFocusOnFCKEditor == false) { // sam - Bug 84611 - don't set focus here (focus will be set by Kirill's FixFocus.js code); just return id of focusable control // just set focus on the "normal" control // objElement.focus(); // return true; return objElement.id; } } } } } } return false; } /* * returns true if the element can receive focus */ function Fev_IsFocusableElement(objElement) { if (objElement && (objElement != null) && Fev_IsElementEnabled(objElement) && Fev_IsElementVisible(objElement) && Fev_IsElementEditable(objElement) ) { var strType = Fev_GetElementType(objElement); if (strType != null) { if ((strType == "text") || (strType == "textarea") || (strType.toLowerCase().indexOf("select") == 0) || (strType.toString().charAt(0) == "s")) { return true; } } } return false; } /* * returns true if the element is enabled */ function Fev_IsElementEnabled(objElement) { if (objElement && (objElement != null)) { if (!(objElement.disabled == false)) { return false; } return true; } return false; } /* * returns true if the element's content is editable by the user */ function Fev_IsElementEditable(objElement) { if (objElement && (objElement != null)) { if (objElement.readOnly) { return false; } var strType = Fev_GetElementType(objElement); if (strType == null) { strType = ""; } if (!objElement.isContentEditable && ((strType.toLowerCase().indexOf("select") != 0)&&(IE || (strType.toLowerCase().indexOf("text") != 0))) && (typeof (objElement.isContentEditable) != 'undefined')) { return false; } return true; } return false; } /* * returns true if the element is visible to the user */ function Fev_IsElementVisible(objElement) { if (objElement && (objElement != null)) { if (objElement.style && (objElement.style != null)) { if (objElement.style.display && (objElement.style.display.toLowerCase() == 'none')) { return false; } if (objElement.style.visibility && (objElement.style.visibility.toLowerCase() == 'hidden')) { return false; } /* if (objElement.style.visibility && (objElement.style.visibility.toLowerCase() == 'inherit')) { var objParentElement = Fev_GetParentElement(objElement); if (objParentElement && (objParentElement != null) && (!Fev_IsElementVisible(objParentElement))) { return false; } } */ } var objParentElement = Fev_GetParentElement(objElement); if (objParentElement && (objParentElement != null)) { return Fev_IsElementVisible(objParentElement); } else { return true; } } return false; } /* * returns true if the element responds directly to Enter key presses * return true for: * Textarea, Select/Dropdown, Input Buttons (Submit/Button/Image/Reset), * A tags * return false for everything else, including: * Input type=[Radio/Checkbox/Text/Password/File] * IMG tags */ function Fev_IsElementUsesEnterKey(objElement) { if (objElement && (objElement != null)) { var strType = Fev_GetElementType(objElement); if (strType != null) strType = strType.toLowerCase(); switch (strType) { case "textarea": case "select": case "submit": case "button": case "image": case "reset": return true; break; case "radio": case "checkbox": case "text": case "password": case "file": case "select-multiple": case "select-single": case "select-one": return false; break; default: break; } var strTagName = Fev_GetElementTagName(objElement); if (strTagName != null) strTagName = strTagName.toLowerCase(); switch (strTagName) { case "textarea": case "select": case "a": return true; break; case "img": case "input": default: break; } } return false; } function Fev_GetParentElement(objElement) { if (objElement && (objElement != null)) { if (objElement.parentNode && (objElement.parentNode != null)) { return objElement.parentNode; } if (objElement.parentElement && (objElement.parentElement != null)) { return objElement.parentElement; } } return null; } function Fev_GetElementType(objElement) { if (objElement && (objElement != null)) { if (objElement.type) { return objElement.type; } } return null; } function Fev_GetElementTagName(objElement) { if (objElement && (objElement != null)) { if (objElement.tagName) { return objElement.tagName; } } return null; } function Fev_GetEventSourceElement(objEvent) { if (objEvent && (objEvent != null)) { // if IE... if (objEvent.srcElement) { return objEvent.srcElement; } // if Firefox... else if (objEvent.target) { return objEvent.target; } } return null; } function Fev_IsEnterKeyPressed(bIgnoreTextAreaEvents) { if (window.event) { var e = window.event; var bIsEnterKeyPress = ((e.keyCode == 13) && (e.type == 'keypress')); if (bIsEnterKeyPress) { if (bIgnoreTextAreaEvents && (bIgnoreTextAreaEvents == true)) { var strType = Fev_GetElementType(Fev_GetEventSourceElement(e)); if (strType != null) strType = strType.toLowerCase(); if (strType == "textarea") { return false; } } return true; } } return false; } function Fev_IsFormSubmitKeyPress(event) { // for IE... if (window.event) { var e = window.event; var bIsEnterKeyPress = ((e.keyCode == 13) && (e.type == 'keypress')); if (bIsEnterKeyPress) { var eventSrc = Fev_GetEventSourceElement(e); if (!Fev_IsElementUsesEnterKey(eventSrc)) { return true; } } } // for Netscape/Firefox else if (event.which) { var bIsEnterKeyPress = (event.which == 13); if (bIsEnterKeyPress) { var eventSrc = Fev_GetEventSourceElement(event); if (!Fev_IsElementUsesEnterKey(eventSrc)) { return true; } } } return false; } /************************************************************************************** * Function : getHRefName() * * Description : We need to get the name of button used in the = 0) { startpos = startpos + "doPostBack('".length; } else { if (navigator.appName == "Netscape") { startpos = anHRef.indexOf('DoPostBackWithOptions(new WebForm_PostBackOptions("'); startpos = startpos + 'DoPostBackWithOptions(new WebForm_PostBackOptions("'.length; } else { // IE startpos = anHRef.indexOf('DoPostBackWithOptions(new%20WebForm_PostBackOptions("'); startpos = startpos + 'DoPostBackWithOptions(new%20WebForm_PostBackOptions("'.length; } } var endpos = anHRef.indexOf("',"); if (endpos < 0) endpos = anHRef.indexOf('",'); anHRef = anHRef.substring(startpos, endpos); return anHRef; } /************************************************************************************** * Function : clickLinkButtonText() * * Description : onclick event handler for HTML table/row shell surrounding button * * text link. Locates the anchor in the center table cell and * * invokes Fev_ClickButton (passing it the anchor's button id) to * * simulate a physical clicking of the button text link. * * Parameters : pButtonTableOrRowNode, html table/row shell receiving the onclick * * event, and which surrounds the button text link to be clicked * * event, browser-generated onclick event object * * Assumptions : Only "button" and "menu item" HTML table/row shells will call this * * function. * * ISD Feature : "Button/Menu Item Image Edges Clickable" * * Authors : Samson Wong * **************************************************************************************/ function clickLinkButtonText(pButtonTableOrRowNode, event) { // make sure to cancel bubbling of clicks. if (!event) return; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); // also check to make sure the target was not the inner area. // target is used by Firefox, srcElement is used by IE if (event.target && event.target.toString().toLowerCase().indexOf("dopostback") > -1) return; if (event.srcElement && event.srcElement.toString().toLowerCase().indexOf("dopostback") > -1) return; var lAnchorNodeArray = pButtonTableOrRowNode.getElementsByTagName("a"); // if "button", "horizontal menu item", "vertical menu item middle row" clicked... if ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1)) { Fev_ClickButton(lAnchorNodeArray.item(0).id, event); } else // if "vertical menu item upper/lower row" clicked... { var lParentTableNode = pButtonTableOrRowNode.parentNode; var lChildrenNodeArray = lParentTableNode.getElementsByTagName("tr"); // alert("clickLinkButtonText(lChildrenNodeArray.length=" + lChildrenNodeArray.length + ")"); if (lChildrenNodeArray != null) { var lClickedRowFound = false; var lCurrentRowItemNumber = 1; // ignore vertical menu edge top row // locate the clicked row (this will either be one row above or below // the row containing the vertical menu item to be clicked); terminate search // before vertical menu edge bottom row while ((lClickedRowFound == false) && (lCurrentRowItemNumber < lChildrenNodeArray.length-1)) { if (lChildrenNodeArray.item(lCurrentRowItemNumber) != pButtonTableOrRowNode) { lCurrentRowItemNumber++; } else { // alert("clickLinkButtonText(lCurrentRowItemNumber=" + lCurrentRowItemNumber + ")"); lClickedRowFound = true; } } if (lClickedRowFound == true) { // if row above first vertical menu item was clicked... if (lCurrentRowItemNumber == 1) { // vertical menu item to be clicked must be below clicked row lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber +1).getElementsByTagName("a"); // if row above vertical menu item was clicked... if ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1)) { Fev_ClickButton(lAnchorNodeArray.item(0).id, event); } } // if row below last vertical menu item was clicked... else if (lCurrentRowItemNumber == (lChildrenNodeArray.length-2)) { // vertical menu item to be clicked must be above clicked row lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber -1).getElementsByTagName("a"); ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1)) { Fev_ClickButton(lAnchorNodeArray.item(0).id, event); } } // if row of any other vertical menu item was clicked... else { lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber +1).getElementsByTagName("a"); // if row above vertical menu item was clicked... if ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1)) { Fev_ClickButton(lAnchorNodeArray.item(0).id, event); } // if row below vertical menu item was clicked... else { lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber -1).getElementsByTagName("a"); ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1)) { Fev_ClickButton(lAnchorNodeArray.item(0).id, event); } } } } } } } function Fev_ClickButton(buttonId, event) { // make sure to cancel bubbling of clicks. if (!event) return; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); var buttonIdWithUnderscores = buttonId; var button = document.getElementById(buttonId); // If button is null, then try replacing $ with _ and look again. if (button == null) { while (buttonIdWithUnderscores.indexOf("$") != -1) { buttonIdWithUnderscores = buttonIdWithUnderscores.replace("$", "_"); } button = document.getElementById(buttonIdWithUnderscores); } // Still nothing? Try appending _Button if (button == null) { button = document.getElementById(buttonIdWithUnderscores + '_Button'); } // Still nothing? Try appending __Button if (button == null) { button = document.getElementById(buttonIdWithUnderscores + '__Button'); } if (button) { // var anHRef = getHRefName(button); // if (anHRef) // { var nav = navigator.appName; if (nav.toUpperCase().indexOf(('Microsoft').toUpperCase()) >= 0) { button.click(); } else { /* for enter key capture on buttons without href's... */ if ((event.keyCode == 13) && (!button.href)) { var l_newEvent = document.createEvent("MouseEvents"); l_newEvent.initEvent("click", true, true); button.dispatchEvent(l_newEvent); } else { var anHRef; // retrieve the entire href, stripping out (if any) the preceding "javascript:" string if (button.href.toLowerCase().indexOf("javascript:") >= 0) { anHRef = button.href.substring("javascript:".length,button.href.length); } else { anHRef = button.href; } // convert all HTML-encoded quotes into true quotes anHRef = anHRef.replace(""",'"'); // convert all HTML-encoded spaces into true-spaces anHRef = anHRef.replace(/%20/g,' '); // call the javascript built-in function to execute the href string (in effect, this is analogous // to IE's button.click(), but without having to do the complicated parsing of the href string // to decide between regular "doPostBack"s and "doPostBackWithOptions"s) eval(anHRef); } } return true; // } } return false; } // returns true if the href uses PostBackWithOptions. function DoesButtonUsePostbackWithOptions(anElement) { var anHRef = anElement.href; var startpos = anHRef.indexOf('PostBackWithOptions'); if (startpos >= 0) { return true; } return false; } //Sets the value or selection of the form element, independent of the element's type. function Fev_SetFormControlValue(objElement, strValue) { var strTagName = Fev_GetElementTagName(objElement); if (strTagName != null) strTagName = strTagName.toLowerCase(); switch (strTagName) { case "textarea": objElement.value = strValue; return true; break; case "select": var currentIndex = objElement.selectedIndex; objElement.value = strValue; if (objElement.selectedIndex < 0) { objElement.selectedIndex = currentIndex; return false; } return true; break; case "input": switch (objElement.type.toLowerCase()) { case "text": case "password": case "hidden": objElement.value = strValue; return true; break; case "file": //can't programatically set the value of file controls return false; case "checkbox": if ((strValue == null) || (strValue == '')) { objElement.checked = false; return true; break; } else if (strValue == objElement.value) { objElement.checked = true; return true; break; } else { //the specified value matches niether the checked nor unchecked state //objElement.checked = true; //objElement.value = strValue; //return true; break; } case "radio": if (strValue == null) { //uncheck all radio buttons in the group objElement.checked = true; objElement.checked = false; return true; break; } else if (strValue == objElement.value) { objElement.checked = true; return true; break; } else { var f = objElement.form; var allRadioButtonsInGroup = f.elements(objElement.name) for (i = 0; i < allRadioButtonsInGroup.length; i++) { var rb = allRadioButtonsInGroup[i]; if (strValue == rb.value) { rb.checked = true; return true; } } //the specified value matches the checked state of none of the radio buttons //objElement.checked = true; //objElement.checked = false; //return true; break; } default: break; } default: break; } return false; } //Inserts the value into a list element, independent of the element's type. function Fev_ReplaceLastListControlOption(objListElement, strValue, strText) { var strTagName = Fev_GetElementTagName(objListElement); if (strTagName != null) strTagName = strTagName.toLowerCase(); switch (strTagName) { case "select": var objOption = objListElement.options[objListElement.options.length-1]; objOption.value = strValue; objOption.text = strText; //objOption.innerText = strText; return true; break; default: break; } return false; } function Fev_HandleFormSubmitKeyPress(buttonId, event) { if (Fev_IsFormSubmitKeyPress(event)) { if (Fev_ClickButton(buttonId, event)) { return true; } } return false; } /************************************************************************************** * Function : refreshFixedHeaderRows() * * Description : Upon expand/collapse of record/table panels, forces a repositioning * * of any scrolling table's "fixed" header row (to it proper * * location above/relative to the rest of the shifted table rows. * * Author : Samson Wong * **************************************************************************************/ function refreshFixedHeaderRows() { var lHeaderRowNodesArray = document.getElementsByTagName("thead"); for (var i=0; i tag node which is clicked upon to initiate toggling * * of expand/collapse * * Assumptions : The region which is expanded/collapsed is the table (with HTML * * id, "CollapsibleRegion") within the sibling (row) of the table * * row which contains the anchorNode. * * Author : Samson Wong * **************************************************************************************/ function toggleExpandCollapse(anchorNode) { var collapsibleNode = anchorNode; // traverse up node tree until the parent table which contains the "dialog_header" and the "collapsible region" is found while (true) { collapsibleNode = collapsibleNode.parentNode; if ( (collapsibleNode != null) && (collapsibleNode.tagName == "TABLE") && ((collapsibleNode.className == "dialog_view") || (collapsibleNode.className == "dv")) ) { break; } } // traverse down node tree to "collapsible region" var childNodesArray = collapsibleNode.getElementsByTagName("TABLE"); for (var i=0; i aLowerBound) { aPageSizeTextboxNode.value = new Number(aPageSizeTextboxNode.value) - 1; } } } } // } } /************************************************************************************** * Function : adjustCurrency() * * Description : onkeyup event handler to increment/decrement currency. * * Parameters : aInputTextbox, html textbox containing the currency value to be * * incremented/decremented * * aCurrencySymbol, the currency symbol which prepended to the * * actual currency value * * aCurrencyDecimalSeparator, the symbol which divides the "whole" * * portion of the currency from the "fractional" part * * aIsCurrencySeparatorAtEnd, boolean indicating whether currency * * symbol trails or precedes currency value * * ISD Feature : "Increment/Decrement Numerical Fields" * * Authors : Samson Wong * **************************************************************************************/ function adjustCurrency(aInputTextbox, aKeyCode, aCurrencySymbol, aCurrencyDecimalSeparator, aIsCurrencySeparatorAtEnd) { // if (justDoIt == true) // { // var lWhichCode = event.keyCode; var lWhichCode = aKeyCode; // if up arrow, or plus key... if ((lWhichCode == 38) || (lWhichCode == 107) || (lWhichCode == 40) || (lWhichCode == 109)) { if ((aCurrencySymbol != "") && (aCurrencyDecimalSeparator != "")) { // strip "+" character if it has been appended to currency value while ((lWhichCode == 107) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "+")) { aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1); } // strip "-" character if it has been appended to currency value while ((lWhichCode == 109) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "-")) { aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1); } // if currency value not initialized... if (aInputTextbox.value == "") { if (aIsCurrencySeparatorAtEnd.indexOf("False") != -1) { // set initial value (with leading currency symbol) aInputTextbox.value = aCurrencySymbol + "1" + aCurrencyDecimalSeparator + "00"; } else { // set initial value (with trailing currency symbol) aInputTextbox.value = "1" + aCurrencyDecimalSeparator + "00" + aCurrencySymbol; } } else { if ((aInputTextbox.value).indexOf(aCurrencyDecimalSeparator) == -1) { aInputTextbox.value = aInputTextbox.value + aCurrencyDecimalSeparator + "00"; } var lCurrencyArray = (aInputTextbox.value).replace(aCurrencySymbol,"").split(aCurrencyDecimalSeparator); var lCurrencyWhole = null; var lParenthesesRepresentationOfNegativeValue = false; // account for "parentheses" representation of negative value if ((aInputTextbox.value.indexOf("(") == 0) && (aInputTextbox.value.indexOf(")") == aInputTextbox.value.length-1)) { lParenthesesRepresentationOfNegativeValue = true; lCurrencyArray[0] = "-" + lCurrencyArray[0]; } if ((lWhichCode == 38) || (lWhichCode == 107)) { lCurrencyWhole = new Number(lCurrencyArray[0].replace(/[^0-9,-]/g,"")) + 1; } // ((lWhichCode == 40) || (lWhichCode == 109)) else { lCurrencyWhole = new Number(lCurrencyArray[0].replace(/[^0-9,-]/g,"")) - 1; } lCurrencyArray[1] = lCurrencyArray[1].replace(/[^0-9]/g,"") if (lCurrencyArray[1].length == 1) { lCurrencyArray[1] = lCurrencyArray[1] + "0"; } var lCurrencyFraction = new Number(lCurrencyArray[1]); if ((lCurrencyFraction < 10) && (lCurrencyFraction >= 0)) { lCurrencyFraction = "0" + lCurrencyFraction; } if (lCurrencyWhole >= 0) { if (aIsCurrencySeparatorAtEnd.indexOf("False") != -1) { aInputTextbox.value = aCurrencySymbol + lCurrencyWhole + aCurrencyDecimalSeparator + lCurrencyFraction; } else { aInputTextbox.value = lCurrencyWhole + aCurrencyDecimalSeparator + lCurrencyFraction + aCurrencySymbol; } } else { if (aIsCurrencySeparatorAtEnd.indexOf("False") != -1) { if (lParenthesesRepresentationOfNegativeValue == false) { aInputTextbox.value = "-" + aCurrencySymbol + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction; } else { aInputTextbox.value = "(" + aCurrencySymbol + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction + ")"; } } else { if (lParenthesesRepresentationOfNegativeValue == false) { aInputTextbox.value = "-" + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction + aCurrencySymbol; } else { aInputTextbox.value = "(" + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction + aCurrencySymbol + ")"; } } } } } } // } } /************************************************************************************** * Function : adjustInteger() * * Description : onkeyup event handler to increment/decrement integer fields. * * Parameters : aInputTextbox, html textbox containing the integer value to be * * incremented/decremented * * ISD Feature : "Increment/Decrement Numerical Fields" * * Authors : Samson Wong * **************************************************************************************/ function adjustInteger(aInputTextbox, aKeyCode) { // if (justDoIt == true) // { // var lWhichCode = event.keyCode; var lWhichCode = aKeyCode; // if up arrow, or plus key... if ((lWhichCode == 38) || (lWhichCode == 107)) { // strip "+" character if it has been appended to integer value while ((lWhichCode == 107) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "+")) { aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1); } // if currency value not initialized or contains invalid characters... if ((aInputTextbox.value == "") || (isNaN(aInputTextbox.value))) { // set initial value aInputTextbox.value = "1"; } else { // myAlert("adjustInteger(aInputTextbox.value=" + aInputTextbox.value + ")"); aInputTextbox.value = new Number(aInputTextbox.value) + 1; } } // if down arrow, or minus key... else if ((lWhichCode == 40) || (lWhichCode == 109)) { // strip "-" character if it has been appended to integer value while ((lWhichCode == 109) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "-")) { aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1); } // if currency value not initialized or contains invalid characters... if ((aInputTextbox.value == "") || (isNaN(aInputTextbox.value))) { // set initial value aInputTextbox.value = "1"; } else { // myAlert("adjustInteger(aInputTextbox.value=" + aInputTextbox.value + ")"); aInputTextbox.value = new Number(aInputTextbox.value) - 1; } } // } } /************************************************************************************** * Function : createNewDate() * * Description : Create and return a new date object based on the value in the * * specified textbox and the current date pattern. * * Parameters : aInputTextbox, textbox containing the current date to be * * incremented/decremented * * Assumptions : parseDatePattern() has already been called, so that the format * * of the date is known. * * ISD Feature : "Increment/Decrement Numerical Fields" * * Authors : Samson Wong * **************************************************************************************/ function createNewDate(aInputTextbox) { // myAlert("createNewDate(aInputTextbox.value=" + aInputTextbox.value + ")"); var rNewDate = new Date(); var lDateStringArray; if (gDateSeparator1 == gDateSeparator2) { lDateStringArray = (aInputTextbox.value).split(gDateSeparator1); } else // (gDateSeparator1 != gDateSeparator2) { var lTempArray1 = (aInputTextbox.value).split(gDateSeparator1); var lDatePortion1 = lTempArray1[0]; var lTempArray2 = lTempArray1[1].split(gDateSeparator2); var lDatePortion2 = lTempArray2[0]; if (lTempArray2.length == 1) { lDateStringArray = new Array(lDatePortion1, lDatePortion2); } else if (lTempArray2.length > 1) { lDateStringArray = new Array(lDatePortion1, lDatePortion2, lTempArray2[1]); } } if (gDatePatternArray != null) { if ((gDatePatternArray.length == 3) && (gDatePatternArray[0].charAt(0) == "m") && (gDatePatternArray[1].charAt(0) == "d") && (gDatePatternArray[2].charAt(0) == "y")) { rNewDate.setTime(Date.parse(aInputTextbox.value)); } else if ((gDatePatternArray.length == 3) && (gDatePatternArray[0].charAt(0) == "d") && (gDatePatternArray[1].charAt(0) == "m") && (gDatePatternArray[2].charAt(0) == "y")) { // Date.parse expects date in mm/dd/yyyy format, so swap date and month portions if date pattern is dd/mm/yyyy rNewDate.setTime(Date.parse(new String(lDateStringArray[1] + gDateSeparator1 + lDateStringArray[0] + gDateSeparator1 + lDateStringArray[2]))); } else { for (var i=0; i<(gDatePatternArray.length); i++) { switch(gDatePatternArray[i].charAt(0)) { case "m": // alert("createNewDate(lDateStringArrayM[" + i + "]=" + lDateStringArray[i] + ")"); // alert("createNewDate(lDateStringArrayM[" + i + "]-1=" + lDateStringArray[i]-1 + ")"); rNewDate.setMonth(lDateStringArray[i]-1); break; case "d": // myAlert("createNewDate(lDateStringArrayD[" + i + "]=" + lDateStringArray[i] + ")"); rNewDate.setDate(lDateStringArray[i]); break; case "y": // myAlert("createNewDate(lDateStringArrayY[" + i + "]=" + lDateStringArray[i] + ")"); // if year string is only two characters long... if (lDateStringArray[i].length == 2) { // prepend default century rNewDate.setYear("20" + lDateStringArray[i]); } else { rNewDate.setYear(lDateStringArray[i]); } break; } } } } return (rNewDate); } /************************************************************************************** * Function : displayDate() * * Description : Display a date in the specified textbox. * * Parameters : aInputTextbox, textbox into which to display date * * aDate, date to be displayed in specified textbox * * Assumptions : parseDatePattern() has already been called, so that the display * * format of the date is known. * * ISD Feature : "Increment/Decrement Numerical Fields" * * Authors : Samson Wong * **************************************************************************************/ function displayDate(aInputTextbox, aDate) { aInputTextbox.value = ""; if (gDatePatternArray != null) { for (var i=0; i<(gDatePatternArray.length); i++) { switch(gDatePatternArray[i].charAt(0)) { case "m": // month pattern is two characters long, but the current month is // only a single digit... if ((gDatePatternArray[i].length == 2) && (aDate.getMonth() < 9)) { // prepend a "0" to month string aInputTextbox.value += "0" + new String(aDate.getMonth()+1); } else { aInputTextbox.value += new String(aDate.getMonth()+1); } break; case "d": aInputTextbox.value += aDate.getDate(); break; case "y": var lDateYearString = new String(aDate.getFullYear()); // if (lDateYearString.length < 4) if (aDate.getFullYear() < 1000) { // correct browser bug which returns "1xx" for the year "20xx" aDate.setFullYear(aDate.getFullYear() + 1900); } aInputTextbox.value += aDate.getFullYear(); break; } // post-pend date separator except for last portion of date if (i == 0) { aInputTextbox.value += gDateSeparator1; } else if ((i == 1) && (gDateDayPosition != 0)) { aInputTextbox.value += gDateSeparator2; } } } } /************************************************************************************** * Function : printPage() * * Description : Invokes the system's print program (to print the current page). * * ISD Feature : "Print Page" * * Authors : Samson Wong * **************************************************************************************/ function printPage() { // if (justDoIt == true) // { window.print(); // } } /************************************************************************************** * Function : emailPage() * * Description : Invokes the system's default e-mail client to send an e-mail with * * the current URL in the body of the message. * * ISD Feature : "E-mail Page" * * Authors : Samson Wong * **************************************************************************************/ function emailPage() { // if (justDoIt == true) // { var lMailStr; lMailStr = "mailto:?body=" + location.href; location.href = lMailStr; // } } /************************************************************************************** * Function : getParentByTagName() * * Description : Return the closest parent with a particular tag name * * Parameters : tag, child tag to be the starting tag to search up * * Parameters : tagname, name of the parent tag * * Assumptions : The edit button is contained in the first cell of the table row in * * focus. * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function getParentByTagName(tag, tagname) { var obj_parent = tag.parentNode; if (!obj_parent) return null; if (obj_parent.tagName.toUpperCase() == tagname.toUpperCase()) return obj_parent; else return getParentByTagName(obj_parent, tagname); } /************************************************************************************** * Function : RedirectByViewButton() * * Description : Invokes the view button server side click event in the selected row * * row) by programmatically clicking the record's edit button. * * Parameters : e, event object * * Assumptions : The view button is contained in the first cell of the table row in * * focus. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function RedirectByViewButton(e) { if (justDoIt == false) return; var iconCellContents = null; var rTableRowClickable = false; var clickedElement; // Firefox if (e.target) { clickedElement = e.target; } // IE or Chrome else { clickedElement = e.srcElement; } if (clickedElement.nodeName == "INPUT" || clickedElement.nodeName == "TEXTAREA" || clickedElement.nodeName == "SELECT" || clickedElement.nodeName == "OPTION" || clickedElement.nodeName == "BUTTON" || clickedElement.nodeName == "LINK" || clickedElement.nodeName == "MAP" || clickedElement.nodeName == "A" || clickedElement.nodeName == "HR") return; var tableRow = getParentByTagName(clickedElement, "TR"); while (tableRow != null) { iconCellContents = tableRow.getElementsByTagName("input"); for (var i = 0; i < iconCellContents.length; i++) { if (iconCellContents[i].id.indexOf("ViewButton") != -1) { iconCellContents[i].click(); rTableRowClickable = true; return rTableRowClickable; } } tableRow = getParentByTagName(tableRow, "TR") } return null; } /************************************************************************************** * Description : Global variables used by the following functions: * * moveToNextTableRow() * * moveToPreviousTableRow() * * moveToThisTableRow() * * updateCurrentTableAndIndex() * * highlightTableRow() * * clickEditButtonOfTableRowInFocus() * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ var justDoIt = true; var currentTable = null; var currentRow = null; var currentRowIndex = 0; /************************************************************************************** * Function : captureUpDownKey() * * Description : Captures an "up/down arrow" and "enter" keyboard event, and calls * * the respective function to process the event. * * Parameters : pTableInFocus, html table receiving the keyboard event * * event, browser-generated event object * * Assumptions : Only table panels will call this function. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function captureUpDownKey(pTableInFocus, event) { // capture current scroll position for "maintain position in tables" feature setCurrentBrowserCoordinates(); if (justDoIt == true) { // if focus is not on a drop-down list, nor the page size entry field (otherwise // drop-down list navigation via up/down/enter keypress takes precedence) if ((event.srcElement == null) || ((event.srcElement.nodeName != "SELECT") && ((event.srcElement.id).indexOf("PageSize") == -1))) { if (event.keyCode) { // if key down... if (event.keyCode == 40) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); moveToNextTableRow(pTableInFocus); } // if key up... else if (event.keyCode == 38) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); moveToPreviousTableRow(pTableInFocus); } // if enter key... else if (event.keyCode == 13) { if (clickEditButtonOfTableRowInFocus() == true) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); } // else let event bubble up to "enter key capture" code for the above column filter button } } } } } /************************************************************************************** * Function : captureEnterKeyInScrollingTable() * * Description : Captures an "enter" keyboard event, and calls the respective * * function to process the event. * * Parameters : pTableInFocus, html table receiving the keyboard event * * event, browser-generated event object * * Assumptions : Only scrolling table panels will call this function. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function captureEnterKeyInScrollingTable(pTableInFocus, event) { // capture current scroll position for "maintain position in tables" feature setCurrentBrowserCoordinates(); if (justDoIt == true) { // for IE... if (event.keyCode) { // if enter key... if (event.keyCode == 13) { if (clickEditButtonOfTableRowInFocus() == true) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); } /* else let event bubble up to "enter key capture" code for the above column filter button */ } // if key down... else if (event.keyCode == 40) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); // ignore because up/down keypress functionality is not supported in scrolling tables } // if key up... else if (event.keyCode == 38) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); // ignore because up/down keypress functionality is not supported in scrolling tables } } // if Netscape/Firefox... else if (event.which) { // if enter key... if (event.which == 13) { if (clickEditButtonOfTableRowInFocus() == true) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); } /* else let event bubble up to "enter key capture" code for the above column filter button */ } // if key down... else if (event.which == 40) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); // ignore because up/down keypress functionality is not supported in scrolling tables } // if key up... else if (event.which == 38) { event.returnValue = false; event.cancel = true; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); // ignore because up/down keypress functionality is not supported in scrolling tables } } } } /************************************************************************************** * Function : moveToNextTableRow() * * Description : Upon "down arrow" keypress, disables "up/down arrow navigation" * * highlight color on the current table row, and enables same on * * the next table row. * * Parameters : pTableInFocus, html table receiving the "down arrow" keyboard event * * Assumptions : None. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function moveToNextTableRow(pTableInFocus) { var tableInFocus; var tableRows; var maxRowIndex; var tableCells; if (justDoIt == true) { if (pTableInFocus != null) { // if focus is still within same table... if (currentTable == pTableInFocus) { // determine the number of rows (including "header row") in this table var maxRowIndex = getNumberOfTableRows(pTableInFocus); if (maxRowIndex > 0) { if (currentRowIndex >= maxRowIndex-1) { // wrap highlighting currentRowIndex = 0; } // if current row is not the last row of this table... if ((currentRowIndex >= 0) && (currentRowIndex < maxRowIndex-1)) { if (tableRowHighlightable(getTableRow(currentRowIndex+1)) == true) { // unhighlight the current row unhighlightTableRow(currentRow); // make previous row of this table the current row currentRowIndex++; // highlight the (new) current row highlightTableRow(getTableRow(currentRowIndex)); } } } } else { // make this new table in focus the current table currentTable = pTableInFocus; moveToNextTableRow(currentTable); } } } } /************************************************************************************** * Function : moveToPreviousTableRow() * * Description : Upon "up arrow" keypress, disables the "up/down arrow navigation" * * highlight color on the current table row, and enables same on * * the previous table row. * * Parameters : pTableInFocus, html table receiving the "down arrow" keyboard event * * Assumptions : None. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function moveToPreviousTableRow(pTableInFocus) { if (justDoIt == true) { if (pTableInFocus != null) { // if focus is still within same table... if (currentTable == pTableInFocus) { // determine the number of rows (including "header row") in this table var maxRowIndex = getNumberOfTableRows(pTableInFocus); if (maxRowIndex > 0) { if (currentRowIndex <= 1) { // wrap highlighting currentRowIndex = maxRowIndex; } // if current row is not the first row of this table... if ((currentRowIndex > 1) && (currentRowIndex <= maxRowIndex)) { if (tableRowHighlightable(getTableRow(currentRowIndex-1)) == true) { // unhighlight the current row unhighlightTableRow(currentRow); // make previous row of this table the current row currentRowIndex--; // highlight the (new) current row highlightTableRow(getTableRow(currentRowIndex)); } } } } else { // make this new table in focus the current table currentTable = pTableInFocus; moveToPreviousTableRow(currentTable); } } } } /************************************************************************************** * Function : moveToThisTableRow() * * Description : Upon "radio button select", disables the "up/down arrow navigation" * * highlight color on the current table row, and enables same on * * the newly selected table row. * * Parameters : pTableCell, "radio button" table cell selected * * Assumptions : Only "radio button" table cells will call this function. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function moveToThisTableRow(pTableCell) { // capture current scroll position for "maintain position in tables" feature setCurrentBrowserCoordinates(); if (justDoIt == true) { if (pTableCell != null) { var tableRow = pTableCell.parentNode; if (tableRow.nodeName == "TD") { tableRow = tableRow.parentNode; } if (tableRowHighlightable(tableRow) == true) { var iconCellContents = tableRow.getElementsByTagName("input"); for (var i=(iconCellContents.length-1); i>=0; i--) { if (iconCellContents[i].type == "checkbox") { iconCellContents[i].focus(); break; } } // if current row highlighted... if (currentTable != null) { unhighlightTableRow(currentRow); } // determine current table and index resulting from focus change updateCurrentTableAndIndex(tableRow); // highlight (new) current table row highlightTableRow(tableRow); } } } } /************************************************************************************** * Function : getTableRow() * * Description : Retrieve the table row specified by pTableRowIndex in the "current" * * table. * * Parameters : pTableRowIndex, index of table row to retrieve * * Assumptions : Global "currentTable" points to a valid table. * * ISD Feature : "Up/Down Arrow Keypress Navigation" * * Authors : Samson Wong & Cocosoft B.V. * **************************************************************************************/ function getTableRow(pTableRowIndex) { var rTableRow = null; if (justDoIt == true) { if (currentTable != null) { var lTableRows = currentTable.getElementsByTagName("tr"); var lTableRowIndex = 1; // if there are enough rows in the current table... if (pTableRowIndex < lTableRows.length) { // while table row not found... for (var i=1; i
with an ID defined by the // global dateSelectorDivID variable. If such a div doesn't yet exist on the HTML // document we're working with, add one. if (!document.getElementById(dateSelectorDivID)) { // don't use innerHTML to update the body, because it can cause global variables // that are currently pointing to objects on the page to have bad references //document.body.innerHTML += "
"; var newNode = document.createElement("div"); newNode.setAttribute("id", dateSelectorDivID); newNode.setAttribute("class", "dpDiv"); newNode.setAttribute("style", "visibility: hidden;"); document.body.appendChild(newNode); } // move the dateSelector div to the proper x,y coordinate and toggle the visiblity var selectorDiv = document.getElementById(dateSelectorDivID); selectorDiv.style.position = "absolute"; selectorDiv.style.left = x + "px"; selectorDiv.style.top = y + "px"; selectorDiv.style.visibility = (selectorDiv.style.visibility == "visible" ? "hidden" : "visible"); selectorDiv.style.display = (selectorDiv.style.display == "" ? "none" : ""); selectorDiv.style.zIndex = 10000; // draw the dateSelector table refreshDateSelector(targetDateField.name, dt.getFullYear(), dt.getMonth(), dt.getDate()); } /************************************************************************************** * Function : refreshDateSelector() * * Description : Function which actually does the drawing of the date selector * * html table. * * Parameters : dateFieldName, html element name of the "date input field" that * * will be filled in if the user picks a date * * year, year to highlight (optional) (default is today's year) * * month, month to highlight (optional) (default is today's month) * * day, day to highlight (optional) (default is today's day) * * Returns: : None. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ function refreshDateSelector(dateFieldName, year, month, day) { // if no arguments are passed, use today's date; otherwise, month and year // are required (if a day is passed, it will be highlighted later) var thisDay = new Date(); if ((month >= 0) && (year > 0)) { thisDay = new Date(year, month, 1); } else { day = thisDay.getDate(); thisDay.setDate(1); } // the calendar will be drawn as a table // you can customize the table elements with a global CSS style sheet, // or by hardcoding style and formatting elements below var crlf = "\r\n"; var TABLE = "" + crlf; var xTABLE = "
" + crlf; var TR = ""; var TR_title = ""; var TR_days = ""; var TR_todaybutton = ""; var xTR = "" + crlf; var TD = ""; if (dayNum == day) html += TD_selected + TD_onclick + DIV_selected + dayNum + xDIV + xTD; else html += TD + TD_onclick + dayNum + xTD; // if this is a Saturday, start a new row if (thisDay.getDay() == 6) html += xTR + TR; // increment the day thisDay.setDate(thisDay.getDate() + 1); } while (thisDay.getDate() > 1) // fill in any trailing blanks if (thisDay.getDay() > 0) { for (i = 6; i > thisDay.getDay(); i--) html += TD_noDay + " " + xTD; } html += xTR; // add a button to allow the user to easily return to today, or close the calendar var today = new Date(); var todayString = "Today is " + dayArrayMed[today.getDay()] + ", " + monthArrayMed[ today.getMonth()] + " " + today.getDate(); html += TR_todaybutton + TD_todaybutton; // sam // html += " "; html += "" html += " "; html += " "; html += " "; html += "
"; html += "" html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += "
Today
"; html += "
"; html += " "; html += "" html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += " "; html += "
Cancel
"; html += "
"; // html += ""; html += xTD + xTR; // and finally, close the table html += xTABLE; document.getElementById(dateSelectorDivID).innerHTML = html; // add an "iFrame shim" to allow the dateSelector to display above selection lists adjustiFrame(); } var mobileCurrentCalendarSender = null; function mobileCalendarShownIntercept(e,h) { if ( e == "years" || e == "months" ) { return; } mobileCurrentCalendarSender(e, h); } function mobileCalendarShown(sender, e) { mobileCurrentCalendarSender = sender; sender._switchMode = mobileCalendarShownIntercept; } /************************************************************************************** * Function : getButtonCode() * * Description : Helper function to construct the html for the previous/next * * month/year buttons. * * Parameters : dateFieldName, html element name of the "date input field" that * * will be filled in if the user picks a date * * dateVal, current date highlighted * * adjust, number of months to move back/forward * * label, previous/next month/year button image to use for this button * * Returns: : The html for previous/next month/year button. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ function getButtonCode(dateFieldName, dateVal, adjust, label) { var newMonth = (dateVal.getMonth () + adjust) % 12; var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12); if (newMonth < 0) { newMonth += 12; newYear += -1; } // sam // return ""; return "
" } /************************************************************************************** * Function : getDateString() * * Description : Convert a JavaScript Date object to a string, based on the * * dateFormat and dateSeparator variables at the beginning of this * * script library. * * Parameters : dateVal, current date highlighted * * Returns: : The highlighted date as a string. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ function getDateString(dateVal) { var dayString = "00" + dateVal.getDate(); var monthString = "00" + (dateVal.getMonth()+1); dayString = dayString.substring(dayString.length - 2); monthString = monthString.substring(monthString.length - 2); switch (dateFormat) { case "dmy" : return dayString + dateSeparator + monthString + dateSeparator + dateVal.getFullYear(); case "ymd" : return dateVal.getFullYear() + dateSeparator + monthString + dateSeparator + dayString; case "mdy" : default : return monthString + dateSeparator + dayString + dateSeparator + dateVal.getFullYear(); } } /************************************************************************************** * Function : getFieldDate() * * Description : Converts a string to a JavaScript Date objec * * Parameters : dateString, date string to be converted into a JavaScript Date * * object. * * Returns: : The date string as a JavaScript Date object. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ function getFieldDate(dateString) { var dateVal; var dArray; var d, m, y; try { dArray = splitDateString(dateString); if (dArray) { switch (dateFormat) { case "dmy" : d = parseInt(dArray[0], 10); m = parseInt(dArray[1], 10) - 1; y = parseInt(dArray[2], 10); break; case "ymd" : d = parseInt(dArray[2], 10); m = parseInt(dArray[1], 10) - 1; y = parseInt(dArray[0], 10); break; case "mdy" : default : d = parseInt(dArray[1], 10); m = parseInt(dArray[0], 10) - 1; y = parseInt(dArray[2], 10); break; } dateVal = new Date(y, m, d); } else if (dateString) { dateVal = new Date(dateString); } else { dateVal = new Date(); } } catch(e) { dateVal = new Date(); } return dateVal; } /************************************************************************************** * Function : splitDateString() * * Description : Splits a date string into an array of elements, using common date * * separators. * * Parameters : dateString, date string to be converted into a JavaScript Date * * object. * * Returns: : The split date array, if operation successful; false, otherwise. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ function splitDateString(dateString) { var dArray; if (dateString.indexOf("/") >= 0) dArray = dateString.split("/"); else if (dateString.indexOf(".") >= 0) dArray = dateString.split("."); else if (dateString.indexOf("-") >= 0) dArray = dateString.split("-"); else if (dateString.indexOf("\\") >= 0) dArray = dateString.split("\\"); else dArray = false; return dArray; } /************************************************************************************** * Function : dateSelectorClosed() * * Description : Update the "date input field" with the date string, and hide the * * date selector. If no date string is passed, just close the * * date selector without changing the field value. * * Parameters : dateFieldName, html element name of the "date input field" that * * will be filled in if the user picks a date * * dateString, date string with which the "date input field" is to be * * updated. * * Returns: : None. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ /** If the page developer has defined a function called dateSelectorClosed anywhere on the page or in an imported library, we will attempt to run that function with the updated field as a parameter. This can be used for such things as date validation, setting default values for related fields, etc. For example, you might have a function like this to validate a start date field: function dateSelectorClosed(dateField) { var dateObj = getFieldDate(dateField.value); var today = new Date(); today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); if (dateField.name == "StartDate") { if (dateObj < today) { // if the date is before today, alert the user and display the dateSelector again alert("Please enter a date that is today or later"); dateField.value = ""; document.getElementById(dateSelectorDivID).style.visibility = "visible"; adjustiFrame(); } else { // if the date is okay, set the EndDate field to 7 days after the StartDate dateObj.setTime(dateObj.getTime() + (7 * 24 * 60 * 60 * 1000)); var endDateField = document.getElementsByName ("EndDate").item(0); endDateField.value = getDateString(dateObj); } } } */ function updateDateField(dateFieldName, dateString) { var targetDateField = document.getElementsByName (dateFieldName).item(0); if (dateString) targetDateField.value = dateString; var selectorDiv = document.getElementById(dateSelectorDivID); selectorDiv.style.visibility = "hidden"; selectorDiv.style.display = "none"; adjustiFrame(); targetDateField.focus(); // after the dateSelector has closed, optionally run a user-defined function called // dateSelectorClosed, passing the field that was just updated as a parameter // (note that this will only run if the user actually selected a date from the dateSelector) if ((dateString) && (typeof(dateSelectorClosed) == "function")) dateSelectorClosed(targetDateField); } /************************************************************************************** * Function : adjustiFrame() * * Description : Uses an "iFrame shim" to deal with problems where the dateSelector * * shows up behind selection list elements, if they're below the * * date selector. * * The problem and solution are described at: * * http://dotnetjunkies.com/WebLog/jking/archive/2003/07/21/488.aspx * * http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx * * Parameters : selectorDiv, html div containing date selector * * iFrameDiv, html div containing iframe shim. * * Returns: : None. * * ISD Feature : "JavaScript Date Selector" * * Authors : Julian Robichaux, http://www.nsftools.com, and Samson Wong * **************************************************************************************/ function adjustiFrame(selectorDiv, iFrameDiv) { // we know that Opera doesn't like something about this, so if we // think we're using Opera, don't even try var is_opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1); if (is_opera) return; // put a try/catch block around the whole thing, just in case try { if (!document.getElementById(iFrameDivID)) { // don't use innerHTML to update the body, because it can cause global variables // that are currently pointing to objects on the page to have bad references //document.body.innerHTML += "