home *** CD-ROM | disk | FTP | other *** search
/ business-86-101-185-173.business.broadband.hu / business-86-101-185-173.business.broadband.hu.zip / business-86-101-185-173.business.broadband.hu / scs.zip / ApplicationWebForm.js < prev    next >
Text File  |  2009-05-20  |  258KB  |  5,333 lines

  1. //<script>
  2.  
  3. var submitcount = 0;
  4.  
  5. function checkDisable(node)
  6. {
  7.     return ((node != null) && (node.disabled != true));
  8. }
  9.  
  10. /*
  11.  * Sets the focus on the first element that should "reasonably" receive it
  12.  */
  13. function Fev_FocusOnFirstFocusableFormElement()
  14. {
  15.     for (i = 0; i < document.forms.length; i++)
  16.     {
  17.         if (Fev_FocusOnDefaultElement(document.forms[i])) return;
  18.         //if (Fev_FocusOnFirstFocusableElement(document.forms[i])) return;
  19.     }
  20. }
  21.  
  22. /*
  23.  * Sets the focus on the first element that is able to receive it
  24.  */
  25. function Fev_FocusOnFirstFocusableElement(objForm)
  26. {
  27.     if (objForm && (objForm != null))
  28.     {
  29.         for (i = 0; i < objForm.length; i++)
  30.         {
  31.             var objElement = objForm.elements[i];
  32.             if (Fev_IsFocusableElement(objElement))
  33.             {
  34.                 objElement.focus();
  35.                 return true;
  36.             }
  37.         }
  38.     }
  39.     return false;
  40. }
  41.  
  42. /**************************************************************************************
  43.  *  Function    : OpwnWindowCentered(URLstring)                                       *
  44.  *  Description : This function is responsible to do a window .open. Open the pop up  *
  45.                   and place it in the center of the screen.                           *
  46.  *  Parameters  : URLstring. the URL for the window.open                              *
  47.  **************************************************************************************/
  48. function OpenWindowCentered(URLstring)
  49. {
  50.     var width = 400;
  51.     var height = 300;
  52.     var left = parseInt((screen.availWidth/2) - (width/2));
  53.     var top = parseInt((screen.availHeight/2) - (height/2));
  54.     var windowFeatures = "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + ",resizable,scrollbars=1";
  55.     helpWindow = window.open (URLstring, "", windowFeatures);
  56.     
  57.     //return false;
  58. }
  59.  
  60. /**************************************************************************************
  61.  *  Function    : SubmitHRefOnce(objElement, msg)                                     *
  62.  *  Description : This function should be used for the onclick HTML attribute for a   *
  63.  *                'a href' to ensure that the button cannot be clicked                *
  64.  *                twice.  It changes the href URL to an alert instead of the previous *
  65.  *                href.  This href will then be reset on the postback, and the button *
  66.  *                will also be enabled by the postback.  Note that this only works    *
  67.  *                for an 'a href' at this time (ThemeButtons included).  It is not    *
  68.  *                tested for any of the other buttons such as ImageButton, LinkButton *
  69.  *                or others.                                                          *
  70.  *  Parameters  : objElement: the button.  Typically it is 'this'                     *
  71.  *                msg: The message to report when the user clicks on the button again *
  72.  **************************************************************************************/
  73. function SubmitHRefOnce(objElement, msg)
  74. {
  75.     var ClientValidate = MyPage_ClientValidate();
  76.     if (ClientValidate){
  77.         submitcount += 1;
  78.     }
  79.     else{
  80.         submitcount = 0;
  81.         return true;
  82.     }
  83.     var strTagName = objElement.tagName;
  84.     if (strTagName != null){
  85.         strTagName = strTagName.toLowerCase();
  86.     }
  87.     else{
  88.         submitcount = 0;
  89.         return true;
  90.     }
  91.     switch (strTagName){
  92.         case "a":
  93.             if (submitcount > 1) {
  94.                 objElement.href = 'javascript:alert("' + msg + '");';
  95.                 submitcount += 1;
  96.                 return false;
  97.             }
  98.  
  99.         case "input":
  100.             if (submitcount > 1) {
  101.                 alert(msg);
  102.                 submitcount += 1;
  103.                 return false;
  104.             }
  105.     }
  106.     return true;
  107. }
  108.  
  109. function MyPage_ClientValidate(validationGroup) {
  110.     Page_InvalidControlToBeFocused = null;
  111.     if (typeof(Page_Validators) == "undefined") {
  112.         return true;
  113.     }
  114.     var i;
  115.     for (i = 0; i < Page_Validators.length; i++) {
  116.         ValidatorValidate(Page_Validators[i], validationGroup, null);
  117.     }
  118.     ValidatorUpdateIsValid();
  119.     //ValidationSummaryOnSubmit(validationGroup);
  120.     Page_BlockSubmit = !Page_IsValid;
  121.     return Page_IsValid;
  122. }
  123. /**************************************************************************************
  124.  *  Function    : FCKeditor_OnComplete()                                              *
  125.  *  Description : Sets focus in the textarea of the FCKEditor (if the method          *
  126.  *                Fev_FocusOnDefaultElement() determines that it appears before the   *
  127.  *                control upon which focus would otherwise normally be set).          *
  128.  *                Note that this method gets called upon loading of the FCKEditor in  *
  129.  *                the page, but only AFTER Fev_FocusOnFirstFocusableFormElement()     *
  130.  *                gets called; also, the focus needs to be set in this FCKEditor-     *
  131.  *                provided JavaScriptAPI method because the FCKEditor does not        *
  132.  *                respond to the conventional JavaScript focus() method.              *
  133.  *  Parameters  : pEditorInstance: reference to the FCKEditor                         *
  134.  **************************************************************************************/
  135. var gSetFocusOnFCKEditor = false;
  136. function FCKeditor_OnComplete(pEditorInstance)
  137. {
  138.     var oEditor = pEditorInstance;
  139.     if (gSetFocusOnFCKEditor == true)
  140.     {
  141.         oEditor.Focus();
  142.         // disable further focus setting (in case there are more than one FCKEditor textarea on page)
  143.         gSetFocusOnFCKEditor = false;
  144.     }
  145. }
  146.  
  147. /*
  148.  * Sets the focus on the first element that should "reasonably" receive it
  149.  */
  150. function Fev_FocusOnDefaultElement(objForm)
  151. {
  152.     if (objForm && (objForm != null))
  153.     {
  154.         for (i = 0; i < objForm.length; i++)
  155.         {
  156.             var objElement = objForm.elements[i];
  157.             
  158.             // if FCKEditor appears before the control upon which focus would normally be set...
  159.             // (note that all FCKEditors have an <input> component with id, "...___Config",
  160.             // so that is used as the identifier)
  161.             if (objElement.id.indexOf("___Config") != -1)
  162.             {  
  163.                 // indicate that focus is to be set (later by FCKeditor_OnComplete()) on the FCKEditor
  164.                 gSetFocusOnFCKEditor = true;
  165.                 return true;
  166.             }
  167.             
  168.             if (Fev_IsFocusableElement(objElement))
  169.             {
  170.                 var strType = Fev_GetElementType(objElement);
  171.                 //we know (strType != null) because it was checked within Fev_IsFocusableElement().
  172.                 if (strType.toLowerCase().indexOf("select") == 0)
  173.                 {
  174.                     //NOTE: SELECT tags are ignored (they interfere with mousewheel scrolling when they have focus)
  175.                 }
  176.                 else
  177.                 {
  178.                     // if object and all it's parents are visible...
  179.                     if (Fev_IsElementVisible(objElement))
  180.                     {
  181.                         // if the FCKEditor does not appear before the control upon which focus would normally be set...
  182.                         if (gSetFocusOnFCKEditor == false)
  183.                         {
  184.                             // just set focus on the "normal" control
  185.                             objElement.focus();
  186.                             return true;
  187.                         }
  188.                     }
  189.                 }
  190.             }
  191.         }
  192.     }
  193.     return false;
  194. }
  195.  
  196. /*
  197.  * returns true if the element can receive focus
  198.  */
  199. function Fev_IsFocusableElement(objElement)
  200. {
  201.     if (objElement && 
  202.         (objElement != null) && 
  203.         Fev_IsElementEnabled(objElement) && 
  204.         Fev_IsElementVisible(objElement) && 
  205.         Fev_IsElementEditable(objElement) )
  206.     {
  207.         var strType = Fev_GetElementType(objElement);
  208.         if (strType != null)
  209.         {
  210.             if ((strType == "text") || (strType == "textarea") || (strType.toString().charAt(0) == "s"))
  211.             {
  212.                 return true;
  213.             }
  214.         }
  215.     }
  216.     return false;
  217. }
  218.  
  219. /*
  220.  * returns true if the element is enabled
  221.  */
  222. function Fev_IsElementEnabled(objElement)
  223. {
  224.     if (objElement && (objElement != null))
  225.     {
  226.         if (!(objElement.disabled == false))
  227.         {
  228.             return false;
  229.         }
  230.         return true;
  231.     }
  232.     return false;
  233. }
  234.  
  235. /*
  236.  * returns true if the element's content is editable by the user
  237.  */
  238. function Fev_IsElementEditable(objElement)
  239. {
  240.     if (objElement && (objElement != null))
  241.     {
  242.         if (objElement.readOnly)
  243.         {
  244.             return false;
  245.         }
  246.         if ((!objElement.isContentEditable) && (typeof(objElement.isContentEditable) != 'undefined'))
  247.         {
  248.             return false;
  249.         }
  250.         return true;
  251.     }
  252.     return false;
  253. }
  254.  
  255. /*
  256.  * returns true if the element is visible to the user
  257.  */
  258. function Fev_IsElementVisible(objElement)
  259. {
  260.     if (objElement && (objElement != null))
  261.     {
  262.         if (objElement.style && (objElement.style != null))
  263.         {
  264.             if (objElement.style.display && (objElement.style.display.toLowerCase() == 'none'))
  265.             {
  266.                 return false;
  267.             }
  268.             if (objElement.style.visibility && (objElement.style.visibility.toLowerCase() == 'hidden'))
  269.             {
  270.                 return false;
  271.             }
  272.             /*
  273.             if (objElement.style.visibility && (objElement.style.visibility.toLowerCase() == 'inherit'))
  274.             {
  275.                 var objParentElement = Fev_GetParentElement(objElement);
  276.                 if (objParentElement && (objParentElement != null) && (!Fev_IsElementVisible(objParentElement)))
  277.                 {
  278.                     return false;
  279.                 }
  280.             }
  281.             */
  282.         }
  283.         
  284.         var objParentElement = Fev_GetParentElement(objElement);
  285.         if (objParentElement && (objParentElement != null))
  286.         {
  287.             return Fev_IsElementVisible(objParentElement);
  288.         }
  289.         else
  290.         {
  291.             return true;
  292.         }
  293.     }
  294.     return false;
  295. }
  296.  
  297. /*
  298.  * returns true if the element responds directly to Enter key presses
  299.  * return true for:
  300.  *     Textarea, Select/Dropdown, Input Buttons (Submit/Button/Image/Reset),
  301.  *     A tags
  302.  * return false for everything else, including:
  303.  *     Input type=[Radio/Checkbox/Text/Password/File]
  304.  *     IMG tags
  305.  */
  306. function Fev_IsElementUsesEnterKey(objElement)
  307. {
  308.     if (objElement && (objElement != null))
  309.     {
  310.         var strType = Fev_GetElementType(objElement);
  311.         if (strType != null) strType = strType.toLowerCase();
  312.         switch (strType)
  313.         {
  314.             case "textarea":
  315.             case "select":
  316.             case "submit":
  317.             case "button":
  318.             case "image":
  319.             case "reset":
  320.                 return true;
  321.                 break;
  322.             case "radio":
  323.             case "checkbox":
  324.             case "text":
  325.             case "password":
  326.             case "file":
  327.             case "select-multiple":
  328.             case "select-single":
  329.                 return false;
  330.                 break;
  331.             default: 
  332.                 break;
  333.         }
  334.  
  335.         var strTagName = Fev_GetElementTagName(objElement);
  336.         if (strTagName != null) strTagName = strTagName.toLowerCase();
  337.         switch (strTagName)
  338.         {
  339.             case "textarea":
  340.             case "select":
  341.             case "a":
  342.                 return true;
  343.                 break;
  344.             case "img":
  345.             case "input":
  346.             default:
  347.                 break;
  348.         }
  349.     }
  350.     return false;
  351. }
  352.  
  353. function Fev_GetParentElement(objElement)
  354. {
  355.     if (objElement && (objElement != null))
  356.     {
  357.         if (objElement.parentNode && (objElement.parentNode != null))
  358.         {
  359.             return objElement.parentNode;
  360.         }
  361.         if (objElement.parentElement && (objElement.parentElement != null))
  362.         {
  363.             return objElement.parentElement;
  364.         }
  365.     }
  366.     return null;
  367. }
  368.  
  369. function Fev_GetElementType(objElement)
  370. {
  371.     if (objElement && (objElement != null))
  372.     {
  373.         if (objElement.type)
  374.         {
  375.             return objElement.type;
  376.         }
  377.     }
  378.     return null;
  379. }
  380.  
  381. function Fev_GetElementTagName(objElement)
  382. {
  383.     if (objElement && (objElement != null))
  384.     {
  385.         if (objElement.tagName)
  386.         {
  387.             return objElement.tagName;
  388.         }
  389.     }
  390.     return null;
  391. }
  392.  
  393. function Fev_GetEventSourceElement(objEvent)
  394. {
  395.     if (objEvent && (objEvent != null))
  396.     {
  397.         // if IE...
  398.         if (objEvent.srcElement)
  399.         {
  400.             return objEvent.srcElement;
  401.         }
  402.         // if Firefox...
  403.         else if (objEvent.target)
  404.         {
  405.             return objEvent.target;
  406.         }
  407.     }
  408.     return null;
  409. }
  410.  
  411. function Fev_IsEnterKeyPressed(bIgnoreTextAreaEvents)
  412. {
  413.     if (window.event)
  414.     {
  415.         var e = window.event;
  416.         var bIsEnterKeyPress = ((e.keyCode == 13) && (e.type == 'keypress'));
  417.         if (bIsEnterKeyPress)
  418.         {
  419.             if (bIgnoreTextAreaEvents && (bIgnoreTextAreaEvents == true))
  420.             {
  421.                 var strType = Fev_GetElementType(Fev_GetEventSourceElement(e));
  422.                 if (strType != null) strType = strType.toLowerCase();
  423.                 if (strType == "textarea")
  424.                 {
  425.                     return false;
  426.                 }
  427.             }
  428.             return true;
  429.         }
  430.     }
  431.     return false;
  432. }
  433.  
  434. function Fev_IsFormSubmitKeyPress(event)
  435. {
  436.     // for IE...
  437.     if (window.event)
  438.     {
  439.         var e = window.event;
  440.         var bIsEnterKeyPress = ((e.keyCode == 13) && (e.type == 'keypress'));
  441.         if (bIsEnterKeyPress)
  442.         {
  443.             var eventSrc = Fev_GetEventSourceElement(e);
  444.             
  445.             if (!Fev_IsElementUsesEnterKey(eventSrc))
  446.             {
  447.                 return true;
  448.             }
  449.         }
  450.     }
  451.     // for Netscape/Firefox
  452.     else if (event.which)
  453.     {
  454.         var bIsEnterKeyPress = (event.which == 13);
  455.         if (bIsEnterKeyPress)
  456.         {
  457.             var eventSrc = Fev_GetEventSourceElement(event);
  458.             if (!Fev_IsElementUsesEnterKey(eventSrc))
  459.             {
  460.                 return true;
  461.             }
  462.         }
  463.     }
  464.     
  465.     return false;
  466. }
  467.  
  468. /**************************************************************************************
  469.  *  Function    : getHRefName()                                                       *
  470.  *  Description : We need to get the name of button used in the <a href tag.  For     *
  471.  *                example, if the href tag = __doPostBack('Menu1$Button') then we     *
  472.  *        need to return Menu1$Button.                        *
  473.  *  Parameters  : anElement: anElement whose HRef value is retrieved and          *
  474.  *        and parsed.                                 *
  475.  **************************************************************************************/
  476. function getHRefName(anElement)
  477. {
  478.     var anHRef = anElement.href;
  479.     
  480.     var startpos = anHRef.indexOf("doPostBack('");
  481.     if (startpos >= 0) {
  482.         startpos = startpos + "doPostBack('".length;
  483.     } else {
  484.         if (navigator.appName == "Netscape") {
  485.             startpos = anHRef.indexOf('DoPostBackWithOptions(new WebForm_PostBackOptions("');
  486.             startpos = startpos + 'DoPostBackWithOptions(new WebForm_PostBackOptions("'.length;
  487.         }
  488.         else { // IE
  489.             startpos = anHRef.indexOf('DoPostBackWithOptions(new%20WebForm_PostBackOptions("');
  490.             startpos = startpos + 'DoPostBackWithOptions(new%20WebForm_PostBackOptions("'.length;
  491.         }
  492.     }
  493.     
  494.     var endpos = anHRef.indexOf("',");
  495.     if (endpos < 0) endpos = anHRef.indexOf('",'); 
  496.     
  497.  
  498.     anHRef = anHRef.substring(startpos, endpos);
  499.     
  500.     return anHRef;
  501. }
  502.  
  503. /**************************************************************************************
  504.  *  Function    : clickLinkButtonText()                                               *
  505.  *  Description : onclick event handler for HTML table/row shell surrounding button   *
  506.  *                    text link.  Locates the anchor in the center table cell and     *
  507.  *                    invokes Fev_ClickButton (passing it the anchor's button id) to  *
  508.  *                    simulate a physical clicking of the button text link.           *
  509.  *  Parameters  : pButtonTableOrRowNode, html table/row shell receiving the onclick   *
  510.  *                    event, and which surrounds the button text link to be clicked   *
  511.  *                event, browser-generated onclick event object                       *
  512.  *  Assumptions : Only "button" and "menu item" HTML table/row shells will call this  *
  513.  *                    function.                                                       *
  514.  *  ISD Feature : "Button/Menu Item Image Edges Clickable"                            *
  515.  *  Authors     : Samson Wong                                                         *
  516.  **************************************************************************************/
  517. function clickLinkButtonText(pButtonTableOrRowNode, event)
  518. {
  519.     // make sure to cancel bubbling of clicks.
  520.     if (!event) return;
  521.     event.cancelBubble = true;
  522.     if (event.stopPropagation) event.stopPropagation();
  523.  
  524.     // also check to make sure the target was not the inner area.   
  525.     // target is used by Firefox, srcElement is used by IE
  526.     if (event.target && event.target.toString().toLowerCase().indexOf("dopostback") > -1) return;
  527.     if (event.srcElement && event.srcElement.toString().toLowerCase().indexOf("dopostback") > -1) return;
  528.  
  529.     var lAnchorNodeArray = pButtonTableOrRowNode.getElementsByTagName("a");
  530.     
  531.     // if "button", "horizontal menu item", "vertical menu item middle row" clicked...
  532.     if ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1))
  533.     {
  534.         Fev_ClickButton(lAnchorNodeArray.item(0).id, event);
  535.     }
  536.     else // if "vertical menu item upper/lower row" clicked...
  537.     {
  538.         var lParentTableNode = pButtonTableOrRowNode.parentNode;
  539.         var lChildrenNodeArray = lParentTableNode.getElementsByTagName("tr");
  540.         // alert("clickLinkButtonText(lChildrenNodeArray.length=" + lChildrenNodeArray.length + ")");
  541.         
  542.         if (lChildrenNodeArray != null)
  543.         {
  544.             var lClickedRowFound = false;
  545.             var lCurrentRowItemNumber = 1; // ignore vertical menu edge top row
  546.  
  547.             // locate the clicked row (this will either be one row above or below
  548.             //     the row containing the vertical menu item to be clicked); terminate search
  549.             //     before vertical menu edge bottom row
  550.             while ((lClickedRowFound == false) && (lCurrentRowItemNumber < lChildrenNodeArray.length-1))
  551.             {
  552.                 if (lChildrenNodeArray.item(lCurrentRowItemNumber) != pButtonTableOrRowNode)
  553.                 {
  554.                     lCurrentRowItemNumber++;
  555.                 }
  556.                 else
  557.                 {
  558.                     // alert("clickLinkButtonText(lCurrentRowItemNumber=" + lCurrentRowItemNumber + ")");
  559.                     lClickedRowFound = true;
  560.                 }
  561.             }
  562.         
  563.             if (lClickedRowFound == true)
  564.             {
  565.                 // if row above first vertical menu item was clicked...
  566.                 if (lCurrentRowItemNumber == 1)
  567.                 {
  568.                     // vertical menu item to be clicked must be below clicked row
  569.                     lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber +1).getElementsByTagName("a");
  570.                     // if row above vertical menu item was clicked...
  571.                     if ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1))
  572.                     {
  573.                         Fev_ClickButton(lAnchorNodeArray.item(0).id, event);
  574.                     }
  575.                 }
  576.                 // if row below last vertical menu item was clicked...
  577.                 else if (lCurrentRowItemNumber == (lChildrenNodeArray.length-2))
  578.                 {
  579.                     // vertical menu item to be clicked must be above clicked row
  580.                     lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber -1).getElementsByTagName("a");
  581.                     ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1))
  582.                     {
  583.                         Fev_ClickButton(lAnchorNodeArray.item(0).id, event);
  584.                     }
  585.                 }
  586.                 // if row of any other vertical menu item was clicked...
  587.                 else
  588.                 {
  589.                     lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber +1).getElementsByTagName("a");
  590.                     // if row above vertical menu item was clicked...
  591.                     if ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1))
  592.                     {
  593.                         Fev_ClickButton(lAnchorNodeArray.item(0).id, event);
  594.                     }
  595.                     // if row below vertical menu item was clicked...
  596.                     else
  597.                     {
  598.                         lAnchorNodeArray = lChildrenNodeArray.item(lCurrentRowItemNumber -1).getElementsByTagName("a");
  599.                         ((lAnchorNodeArray != null) && (lAnchorNodeArray.length == 1))
  600.                         {
  601.                             Fev_ClickButton(lAnchorNodeArray.item(0).id, event);
  602.                         }
  603.                     }
  604.                 }
  605.             }
  606.         }
  607.     }
  608. }
  609.  
  610.  
  611. function Fev_ClickButton(buttonId, event)
  612. {
  613.     // make sure to cancel bubbling of clicks.
  614.     if (!event) return;
  615.     event.cancelBubble = true;
  616.     if (event.stopPropagation) event.stopPropagation();
  617.  
  618.     var buttonIdWithUnderscores = buttonId;
  619.  
  620.     var button = document.getElementById(buttonId);
  621.     
  622.     // If button is null, then try replacing $ with _ and look again.
  623.     if (button == null)
  624.     {
  625.         while (buttonIdWithUnderscores.indexOf("$") != -1)
  626.         {
  627.              buttonIdWithUnderscores = buttonIdWithUnderscores.replace("$", "_");
  628.         }
  629.  
  630.         button = document.getElementById(buttonIdWithUnderscores);
  631.     }
  632.  
  633.     // Still nothing?  Try appending _Button
  634.     if (button == null)
  635.     {
  636.         button = document.getElementById(buttonIdWithUnderscores + '_Button');
  637.     }
  638.  
  639.     // Still nothing?  Try appending __Button
  640.     if (button == null)
  641.     {
  642.         button = document.getElementById(buttonIdWithUnderscores + '__Button');
  643.     }
  644.  
  645.     if (button)
  646.     {
  647.         // var anHRef = getHRefName(button);
  648.         // if (anHRef)
  649.         // {
  650.  
  651.             var nav = navigator.appName;
  652.             if (nav.toUpperCase().indexOf(('Microsoft').toUpperCase()) >= 0)
  653.             {
  654.                 button.click();             
  655.             }
  656.             else
  657.             {
  658.                 var anHRef;
  659.                 // retrieve the entire href, stripping out (if any) the preceding "javascript:" string
  660.                 if (button.href.toLowerCase().indexOf("javascript:") >= 0)
  661.                 {
  662.                     anHRef = button.href.substring("javascript:".length,button.href.length);
  663.                 }
  664.                 else
  665.                 {
  666.                     anHRef = button.href;
  667.                 }
  668.  
  669.                 // convert all HTML-encoded quotes into true quotes
  670.                 anHRef = anHRef.replace(""",'"');
  671.                 
  672.                 // convert all HTML-encoded spaces into true-spaces
  673.                 anHRef = anHRef.replace(/%20/g,' ');
  674.  
  675.                 // call the javascript built-in function to execute the href string (in effect, this is analogous
  676.                 //     to IE's button.click(), but without having to do the complicated parsing of the href string
  677.                 //     to decide between regular "doPostBack"s and "doPostBackWithOptions"s)
  678.                 eval(anHRef);
  679.                 
  680.                 /*
  681.                 if (DoesButtonUsePostbackWithOptions(button)) 
  682.  
  683.                 {
  684.                     WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(buttonId, "", true, "", "", false, true));
  685.                 }
  686.                 else
  687.                 {
  688.                     __doPostBack(anHRef, "");
  689.                 }                
  690.                 */                
  691.             }
  692.           
  693.             return true;
  694.         // }
  695.     }
  696.     return false;
  697. }
  698.  
  699. // returns true if the href uses PostBackWithOptions.
  700. function DoesButtonUsePostbackWithOptions(anElement)
  701.  
  702. {
  703.     var anHRef = anElement.href;
  704.     var startpos = anHRef.indexOf('PostBackWithOptions');
  705.     if (startpos >= 0) 
  706.     {
  707.         return true;
  708.     }
  709.     return false;
  710. }
  711. //Sets the value or selection of the form element, independent of the element's type.
  712. function Fev_SetFormControlValue(objElement, strValue)
  713. {
  714.     var strTagName = Fev_GetElementTagName(objElement);
  715.     if (strTagName != null) strTagName = strTagName.toLowerCase();
  716.     switch (strTagName)
  717.     {
  718.         case "textarea":
  719.             objElement.value = strValue;
  720.             return true;
  721.             break;
  722.         case "select":
  723.             var currentIndex = objElement.selectedIndex;
  724.             objElement.value = strValue;
  725.             if (objElement.selectedIndex < 0)
  726.             {
  727.                 objElement.selectedIndex = currentIndex;
  728.                 return false;
  729.             }
  730.             return true;
  731.             break;
  732.         case "input":
  733.             switch (objElement.type.toLowerCase())
  734.             {
  735.                 case "text":
  736.                 case "password":
  737.                 case "hidden":
  738.                     objElement.value = strValue;
  739.                     return true;
  740.                     break;
  741.                 case "file":
  742.                     //can't programatically set the value of file controls
  743.                     return false;
  744.                 case "checkbox":
  745.                     if ((strValue == null) || (strValue == ''))
  746.                     {
  747.                         objElement.checked = false;
  748.                         return true;
  749.                         break;
  750.                     }
  751.                     else if (strValue == objElement.value)
  752.                     {
  753.                         objElement.checked = true;
  754.                         return true;
  755.                         break;
  756.                     }
  757.                     else
  758.                     {
  759.                         //the specified value matches niether the checked nor unchecked state
  760.                         //objElement.checked = true;
  761.                         //objElement.value = strValue;
  762.                         //return true;
  763.                         break;
  764.                     }
  765.                 case "radio":
  766.                     if (strValue == null)
  767.                     {
  768.                         //uncheck all radio buttons in the group
  769.                         objElement.checked = true;
  770.                         objElement.checked = false;
  771.                         return true;
  772.                         break;
  773.                     }
  774.                     else if (strValue == objElement.value)
  775.                     {
  776.                         objElement.checked = true;
  777.                         return true;
  778.                         break;
  779.                     }
  780.                     else
  781.                     {
  782.                         var f = objElement.form;
  783.                         var allRadioButtonsInGroup = f.elements(objElement.name)
  784.                         for (i = 0; i < allRadioButtonsInGroup.length; i++)
  785.                         {
  786.                             var rb = allRadioButtonsInGroup[i];
  787.                             if (strValue == rb.value)
  788.                             {
  789.                                 rb.checked = true;
  790.                                 return true;
  791.                             }
  792.                         }
  793.                         //the specified value matches the checked state of none of the radio buttons
  794.                         //objElement.checked = true;
  795.                         //objElement.checked = false;
  796.                         //return true;
  797.                         break;
  798.                     }
  799.                 default:
  800.                     break;
  801.             }
  802.         default:
  803.             break;
  804.     }
  805.     return false;
  806. }
  807.  
  808. //Inserts the value into a list element, independent of the element's type.
  809. function Fev_ReplaceLastListControlOption(objListElement, strValue, strText)
  810. {
  811.     var strTagName = Fev_GetElementTagName(objListElement);
  812.     if (strTagName != null) strTagName = strTagName.toLowerCase();
  813.     switch (strTagName)
  814.     {
  815.         case "select":
  816.             var objOption = objListElement.options[objListElement.options.length-1];
  817.             objOption.value = strValue;
  818.             objOption.text = strText;
  819.             //objOption.innerText = strText;
  820.             return true;
  821.             break;
  822.         default:
  823.             break;
  824.     }
  825.     return false;
  826. }
  827.  
  828. function Fev_HandleFormSubmitKeyPress(buttonId, event)
  829. {
  830.     if (Fev_IsFormSubmitKeyPress(event))
  831.     {
  832.         if (Fev_ClickButton(buttonId, event))
  833.         {
  834.             var nav = navigator.appName;
  835.             if (nav.toUpperCase().indexOf(('Microsoft').toUpperCase()) >= 0)
  836.             {
  837.                 // cancel (IE's upward) bubbling so that only the innermost/default enter key
  838.                 // action is executed
  839.                 event.cancelBubble = true;
  840.             }
  841.             else
  842.             {
  843.                 // allow (Firefox's downward) bubbling so that the innermost/default enter key
  844.                 // action is executed 
  845.                 event.cancelBubble = false;
  846.             }
  847.             return true;
  848.         }
  849.     }
  850.     return false;
  851. }
  852.  
  853.  
  854. /**************************************************************************************
  855.  *  Function    : refreshFixedHeaderRows()                                            *
  856.  *  Description : Upon expand/collapse of record/table panels, forces a repositioning *
  857.  *                    of any scrolling table's "fixed" header row (to it proper       *
  858.  *                    location above/relative to the rest of the shifted table rows.  *
  859.  *  Author      : Samson Wong                                                         *
  860.  **************************************************************************************/
  861. function refreshFixedHeaderRows()
  862. {
  863.     var lHeaderRowNodesArray = document.getElementsByTagName("thead");
  864.     for (var i=0; i<lHeaderRowNodesArray.length; i++)
  865.     {
  866.         var lHeaderRowNode = lHeaderRowNodesArray[i];
  867.         if (lHeaderRowNode.className == "fixedHeader")
  868.         {
  869.             lHeaderRowNode.style.position = "absolute";
  870.             lHeaderRowNode.style.position = "relative";
  871.         }
  872.     }
  873. }
  874.  
  875.  
  876. /**************************************************************************************
  877.  *  Function    : toggleExpandCollapse()                                              *
  878.  *  Description : Toggles the expanding and collapsing of the content region of       *
  879.  *                    record and table panels; also swaps the "expand/collapse" icon, *
  880.  *                    and "total records" count based upon the current                *
  881.  *                    expand/collapse state.                                          *
  882.  *  Parameters  : anchorNode, <a> tag node which is clicked upon to initiate toggling *
  883.  *                    of expand/collapse                                              *
  884.  *  Assumptions : The region which is expanded/collapsed is the table (with HTML      *
  885.  *                    id, "CollapsibleRegion") within the sibling (row) of the table  *
  886.  *                    row which contains the anchorNode.                              *
  887.  *  Author      : Samson Wong                                                         *
  888.  **************************************************************************************/
  889. function toggleExpandCollapse(anchorNode)
  890. {
  891.     var collapsibleNode = anchorNode;
  892.         
  893.     // traverse up node tree until the parent table which contains the "dialog_header" and the "collapsible region" is found
  894.     while (true)
  895.     {
  896.         collapsibleNode = collapsibleNode.parentNode;
  897.         if ( (collapsibleNode != null) &&
  898.              (collapsibleNode.tagName == "TABLE") &&
  899.              ((collapsibleNode.className == "dialog_view") || (collapsibleNode.className == "dv"))
  900.            )
  901.         {
  902.             break;
  903.         }
  904.     }
  905.     
  906.     // traverse down node tree to "collapsible region"    
  907.     var childNodesArray = collapsibleNode.getElementsByTagName("TABLE"); 
  908.     for (var i=0; i<childNodesArray.length; i++)
  909.     {
  910.         if (childNodesArray[i].id == "CollapsibleRegion")
  911.         {
  912.             collapsibleNode = childNodesArray[i];
  913.                break;         
  914.         }
  915.     }
  916.     
  917.     // make sure this node is a collapsible region before collapsing
  918.     if ((collapsibleNode != null) && (collapsibleNode.id == "CollapsibleRegion") && (collapsibleNode.tagName == "TABLE"))
  919.     {
  920.         collapsibleNode.style.display = (collapsibleNode.style.display == "") ? "none" : "";
  921.  
  922.         // reposition any scrolling tables' "fixed header" row
  923.         refreshFixedHeaderRows();        
  924.     }
  925.     
  926.     // traverse to image node (note that for both Netscape and IE, this is the first child of anchor tag)
  927.     var imageNode = anchorNode.childNodes.item(0);
  928.  
  929.     // make sure this node contains the expand/collapse image before swapping icon
  930.     if ((imageNode.id == "ExpandCollapseIcon") && (imageNode.tagName == "IMG"))
  931.     {
  932.         // show appropriate icon for current expand/collapse state
  933.         imageNode.src = (collapsibleNode.style.display == "") ? "../Images/DialogHeaderIconCollapse.gif" : "../Images/DialogHeaderIconExpand.gif";
  934.         
  935.         // show appropriate tool tip for current expand/collapse state (for section 508 compliance)
  936.         // imageNode.alt = (collapsibleNode.style.display == "") ? "Collapse panel" : "Expand panel";
  937.         // imageNode.title = (collapsibleNode.style.display == "") ? "Collapse panel" : "Expand panel";
  938.     }
  939.     
  940.     
  941.     // traverse up node tree until the parent table which contains the "dialog_header" and the "collapsible region" is found
  942.     var totalRecordsNode = anchorNode;
  943.  
  944.     while (true)
  945.     {
  946.         totalRecordsNode = totalRecordsNode.parentNode;
  947.            if ( (totalRecordsNode != null) &&
  948.              (totalRecordsNode.tagName == "TD") &&
  949.              ((totalRecordsNode.className == "dialog_header") || (totalRecordsNode.className == "dh"))
  950.            )
  951.         {
  952.             break;
  953.         }
  954.     }
  955.     
  956.     // traverse down node tree to "collapsible region total records"    
  957.     var childNodesArray = totalRecordsNode.getElementsByTagName("TABLE"); 
  958.     for (var i=0; i<childNodesArray.length; i++)
  959.     {
  960.         if (childNodesArray[i].id == "CollapsibleRegionTotalRecords")
  961.         {
  962.             totalRecordsNode = childNodesArray[i];
  963.                break;         
  964.         }
  965.     }
  966.     
  967.     // make sure this node contains the total records count before toggling
  968.     if ((totalRecordsNode != null) && (totalRecordsNode.id == "CollapsibleRegionTotalRecords") && (totalRecordsNode.tagName == "TABLE"))
  969.     {
  970.         // show total records count if panel in collapsed state
  971.         totalRecordsNode.style.display = (totalRecordsNode.style.display == "") ? "none" : "";
  972.     }   
  973.     
  974.     return false;
  975. }
  976.  
  977.  
  978. /**************************************************************************************
  979.  *  Function    : toggleRegions()                                                     *
  980.  *  Description : Cycles between "hiding filter", "hiding filters and pagination",    *
  981.  *                    "hiding all" (including table data), and "showing all" regions. *
  982.  *  Parameters  : aRegionName, html id of the region to be collapsed                  *
  983.  *  ISD Feature : "Show/Hide Filter/Pagination"                                       *
  984.  *  Authors     : Samson Wong                                                         *
  985.  **************************************************************************************/
  986. function toggleRegions(aAnchorNode)
  987. {
  988.     var lToggleRegionIconNode = aAnchorNode.childNodes.item(0);
  989.  
  990.     if (lToggleRegionIconNode.id == "ToggleRegionIcon")
  991.     {
  992.         if (lToggleRegionIconNode.src.indexOf("ToggleHideFilters") != -1)
  993.         {
  994.             lToggleRegionIconNode.src = lToggleRegionIconNode.src.replace("ToggleHideFilters","ToggleHidePagination");
  995.             // lToggleRegionIconNode.alt = "Hide Pagination";
  996.             
  997.             var lFilterRegionNode = getRegion(aAnchorNode, "FilterRegion");
  998.             if (lFilterRegionNode != null)
  999.             {
  1000.                 lFilterRegionNode.style.display = "none";
  1001.             }
  1002.             var lCategoryRegionNode = getRegion(aAnchorNode, "CategoryRegion");
  1003.             if (lCategoryRegionNode != null)
  1004.             {
  1005.                 lCategoryRegionNode.style.display = "none";
  1006.             }
  1007.         }
  1008.         else if (lToggleRegionIconNode.src.indexOf("ToggleHidePagination") != -1)
  1009.         {
  1010.             lToggleRegionIconNode.src = lToggleRegionIconNode.src.replace("ToggleHidePagination","ToggleHideAll");
  1011.             // lToggleRegionIconNode.alt = "Hide All";
  1012.  
  1013.             var lPaginationRegionNode = getRegion(aAnchorNode, "PaginationRegion");
  1014.             var lTotalRecordsRegionNode = getRegion(aAnchorNode, "CollapsibleRegionTotalRecords");
  1015.             if ((lPaginationRegionNode != null) && (lTotalRecordsRegionNode != null))
  1016.             {
  1017.                 lPaginationRegionNode.style.display = "none";
  1018.                 lTotalRecordsRegionNode.style.display = "";
  1019.             }
  1020.         }
  1021.         else if (lToggleRegionIconNode.src.indexOf("ToggleHideAll") != -1)
  1022.         {
  1023.             lToggleRegionIconNode.src = lToggleRegionIconNode.src.replace("ToggleHideAll","ToggleShowAll");
  1024.             // lToggleRegionIconNode.alt = "Show All";
  1025.  
  1026.             var lCollapsibleRegionNode = getRegion(aAnchorNode, "CollapsibleRegion");
  1027.             if (lCollapsibleRegionNode != null)
  1028.             {
  1029.                 lCollapsibleRegionNode.style.display = "none";
  1030.             }
  1031.         }
  1032.         else if (lToggleRegionIconNode.src.indexOf("ToggleShowAll") != -1)
  1033.         {
  1034.             lToggleRegionIconNode.src = lToggleRegionIconNode.src.replace("ToggleShowAll","ToggleHideFilters");
  1035.             // lToggleRegionIconNode.alt = "Hide Filters";
  1036.  
  1037.             var lCollapsibleRegionNode= getRegion(aAnchorNode, "CollapsibleRegion");
  1038.             if (lCollapsibleRegionNode != null)
  1039.             {
  1040.                 lCollapsibleRegionNode.style.display = "";
  1041.             }
  1042.             var lFilterRegionNode = getRegion(aAnchorNode, "FilterRegion");
  1043.             if (lFilterRegionNode != null)
  1044.             {
  1045.                 lFilterRegionNode.style.display = "";
  1046.             }
  1047.             var lCategoryRegionNode = getRegion(aAnchorNode, "CategoryRegion");
  1048.             if (lCategoryRegionNode != null)
  1049.             {
  1050.                 lCategoryRegionNode.style.display = "";
  1051.             }
  1052.             var lPaginationRegionNode = getRegion(aAnchorNode, "PaginationRegion");
  1053.             if (lPaginationRegionNode != null)
  1054.             {
  1055.                 lPaginationRegionNode.style.display = "";
  1056.             }
  1057.             var lTotalRecordsRegionNode = getRegion(aAnchorNode, "CollapsibleRegionTotalRecords");
  1058.             if (lTotalRecordsRegionNode != null)
  1059.             {
  1060.                 lTotalRecordsRegionNode.style.display = "none";
  1061.             }
  1062.         }
  1063.  
  1064.         // reposition any scrolling tables' "fixed header" row
  1065.         refreshFixedHeaderRows();                
  1066.     }
  1067. }
  1068.  
  1069.  
  1070. /**************************************************************************************
  1071.  *  Function    : getRegion()                                                         *
  1072.  *  Description : Retrieves a reference to the specified collapsible region           *
  1073.  *                   associated with the table containing the specified anchor node.  *
  1074.  *  Parameters  : aAnchorNode, toggle regions button which has been clicked           *
  1075.  *                aRegionName, region to be collapsed                                 *
  1076.  *  ISD Feature : "Show/Hide Filter/Pagination"                                       *
  1077.  *  Authors     : Samson Wong                                                         *
  1078.  **************************************************************************************/
  1079. function getRegion(aAnchorNode, aRegionName)
  1080. {
  1081.     var rRegionNode = null;
  1082.     var lMainTableNode = aAnchorNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
  1083.     // alert("getRegion(lMainTableNode.nodeName=" + lMainTableNode.nodeName + ",lMainTableNode.className=" + lMainTableNode.className + ")");
  1084.     var lContainedTableNodesArray = lMainTableNode.getElementsByTagName("table");
  1085.     
  1086.     // alert("getRegion(lContainedTableNodesArray.length=" + lContainedTableNodesArray.length + ")");
  1087.     for (var i=0;i<lContainedTableNodesArray.length;i++)
  1088.     {
  1089.         if (lContainedTableNodesArray[i].id == aRegionName)
  1090.         {
  1091.             // alert("getRegion(lContainedTableNodesArray[" + i + "].id=" + lContainedTableNodesArray[i].id + ")");
  1092.             rRegionNode = lContainedTableNodesArray[i];
  1093.             break;
  1094.         }
  1095.     }
  1096.     
  1097.     // alert("getRegion(rRegionNodeIsNull=" + (rRegionNode == null) + ")");
  1098.     return(rRegionNode);
  1099. }
  1100.  
  1101.  
  1102. /**************************************************************************************
  1103.  *  Function    : adjustPageSize()                                                    *
  1104.  *  Description : onkeyup event handler to increment/decrement page size value within *
  1105.  *                    specified lower and upper bounds.                               *
  1106.  *  Parameters  : aPageSizeTextboxNode, table cell containing page size textbox       *
  1107.  *                    which caught the onkeyup event)                                 *
  1108.  *                event, onkeyup event                                                *
  1109.  *                aLowerBound, lower bound for the page size value                    *
  1110.  *                aUpperBound, upper bound for the page size value                    *
  1111.  *  ISD Feature : "Increment/Decrement Numerical Fields"                              *
  1112.  *  Authors     : Samson Wong                                                         *
  1113.  **************************************************************************************/
  1114. function adjustPageSize(aPageSizeTextboxNode, aKeyCode, aLowerBound, aUpperBound)
  1115. {
  1116.     // if (justDoIt == true)
  1117.     // {
  1118.         // myAlert("adjustPage(event.which=" + event.which + ",event.keyCode=" + event.keyCode + ")");
  1119.         
  1120.         if (aPageSizeTextboxNode != null)
  1121.         {
  1122.             var lWhichCode = aKeyCode;
  1123.             
  1124.             // if up arrow, or plus key...
  1125.             if ((lWhichCode == 38) || (lWhichCode == 107))
  1126.             {
  1127.                 // strip "+" character if it has been appended to page size value
  1128.                 while ((lWhichCode == 107) && (aPageSizeTextboxNode.value.charAt(aPageSizeTextboxNode.value.length-1) == "+"))
  1129.                 {
  1130.                     aPageSizeTextboxNode.value = (aPageSizeTextboxNode.value).substring(0,aPageSizeTextboxNode.value.length-1);
  1131.                 }
  1132.                 
  1133.                 // if page size not initialized or contains invalid characters...
  1134.                 if ((aPageSizeTextboxNode.value == "") || (isNaN(aPageSizeTextboxNode.value)))
  1135.                 {
  1136.                     // set initial value as "1"
  1137.                     aPageSizeTextboxNode.value = 10;
  1138.                 }
  1139.                 else
  1140.                 {
  1141.                     // upper bounds check
  1142.                     if (aPageSizeTextboxNode.value < aUpperBound)
  1143.                     {
  1144.                         aPageSizeTextboxNode.value = new Number(aPageSizeTextboxNode.value) + 1;
  1145.                     }
  1146.                 }
  1147.             }
  1148.             // else if down arrow, or minus key...
  1149.             else if ((lWhichCode == 40) || (lWhichCode == 109))
  1150.             {
  1151.                 // strip "-" character if it has been appended to page size value
  1152.                 while ((lWhichCode == 109) && (aPageSizeTextboxNode.value.charAt(aPageSizeTextboxNode.value.length-1) == "-"))
  1153.                 {
  1154.                     aPageSizeTextboxNode.value = (aPageSizeTextboxNode.value).substring(0,aPageSizeTextboxNode.value.length-1);
  1155.                 }
  1156.                 
  1157.                 // if page size not initialized or contains invalid characters...
  1158.                 if ((aPageSizeTextboxNode.value == "") || (isNaN(aPageSizeTextboxNode.value)))
  1159.                 {
  1160.                     // set initial value as "1"
  1161.                     aPageSizeTextboxNode.value = 10;
  1162.                 }
  1163.                 else {
  1164.                     // lower bounds check
  1165.                     if (aPageSizeTextboxNode.value > aLowerBound)
  1166.                     {
  1167.                         aPageSizeTextboxNode.value = new Number(aPageSizeTextboxNode.value) - 1;
  1168.                     }
  1169.                 }
  1170.             }
  1171.         }
  1172.     // }
  1173. }
  1174.  
  1175.  
  1176. /**************************************************************************************
  1177.  *  Function    : adjustCurrency()                                                    *
  1178.  *  Description : onkeyup event handler to increment/decrement currency.              *
  1179.  *  Parameters  : aInputTextbox, html textbox containing the currency value to be     *
  1180.  *                    incremented/decremented                                         *
  1181.  *                aCurrencySymbol, the currency symbol which prepended to the         *
  1182.  *                    actual currency value                                           *
  1183.  *                aCurrencyDecimalSeparator, the symbol which divides the "whole"     *
  1184.  *                    portion of the currency from the "fractional" part              *
  1185.  *                  aIsCurrencySeparatorAtEnd, boolean indicating whether currency      *
  1186.  *                    symbol trails or precedes currency value                        *
  1187.  *  ISD Feature : "Increment/Decrement Numerical Fields"                              *
  1188.  *  Authors     : Samson Wong                                                         *
  1189.  **************************************************************************************/
  1190. function adjustCurrency(aInputTextbox, aKeyCode, aCurrencySymbol, aCurrencyDecimalSeparator, aIsCurrencySeparatorAtEnd)
  1191. {
  1192.     // if (justDoIt == true)
  1193.     // {
  1194.         // var lWhichCode = event.keyCode;
  1195.         var lWhichCode = aKeyCode;
  1196.         
  1197.         // if up arrow, or plus key...
  1198.         if ((lWhichCode == 38) || (lWhichCode == 107) || (lWhichCode == 40) || (lWhichCode == 109))
  1199.         {
  1200.             if ((aCurrencySymbol != "") && (aCurrencyDecimalSeparator != ""))
  1201.             {
  1202.                 // strip "+" character if it has been appended to currency value
  1203.                 while ((lWhichCode == 107) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "+"))
  1204.                 {
  1205.                     aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1);
  1206.                 }
  1207.  
  1208.                 // strip "-" character if it has been appended to currency value
  1209.                 while ((lWhichCode == 109) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "-"))
  1210.                 {
  1211.                     aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1);
  1212.                 }
  1213.                     
  1214.                 // if currency value not initialized...
  1215.                 if (aInputTextbox.value == "")
  1216.                 {
  1217.                     if (aIsCurrencySeparatorAtEnd.indexOf("False") != -1)
  1218.                     {
  1219.                         // set initial value (with leading currency symbol)
  1220.                         aInputTextbox.value = aCurrencySymbol + "1" + aCurrencyDecimalSeparator + "00";
  1221.                     }
  1222.                     else
  1223.                     {
  1224.                         // set initial value (with trailing currency symbol)
  1225.                         aInputTextbox.value = "1" + aCurrencyDecimalSeparator + "00" + aCurrencySymbol;
  1226.                     }
  1227.                 }
  1228.                 else
  1229.                 {
  1230.                     if ((aInputTextbox.value).indexOf(aCurrencyDecimalSeparator) == -1)
  1231.                     {
  1232.                         aInputTextbox.value = aInputTextbox.value + aCurrencyDecimalSeparator + "00";
  1233.                     }
  1234.  
  1235.                     var lCurrencyArray = (aInputTextbox.value).replace(aCurrencySymbol,"").split(aCurrencyDecimalSeparator);
  1236.                     
  1237.                     var lCurrencyWhole = null;
  1238.                     var lParenthesesRepresentationOfNegativeValue = false;
  1239.                     // account for "parentheses" representation of negative value
  1240.                     if ((aInputTextbox.value.indexOf("(") == 0) && (aInputTextbox.value.indexOf(")") == aInputTextbox.value.length-1))
  1241.                     {
  1242.                         lParenthesesRepresentationOfNegativeValue = true;
  1243.                         lCurrencyArray[0] = "-" + lCurrencyArray[0];
  1244.                     }
  1245.                     
  1246.                     if ((lWhichCode == 38) || (lWhichCode == 107))
  1247.                     {
  1248.                         lCurrencyWhole = new Number(lCurrencyArray[0].replace(/[^0-9,-]/g,"")) + 1;
  1249.                     }
  1250.                     // ((lWhichCode == 40) || (lWhichCode == 109))
  1251.                     else
  1252.                     {
  1253.                         lCurrencyWhole = new Number(lCurrencyArray[0].replace(/[^0-9,-]/g,"")) - 1;
  1254.                     }
  1255.                     
  1256.                     lCurrencyArray[1] = lCurrencyArray[1].replace(/[^0-9]/g,"")
  1257.                     if (lCurrencyArray[1].length == 1)
  1258.                     {
  1259.                         lCurrencyArray[1] = lCurrencyArray[1] + "0";
  1260.                     }
  1261.                     
  1262.                     var lCurrencyFraction = new Number(lCurrencyArray[1]);
  1263.                     
  1264.                     if ((lCurrencyFraction < 10) && (lCurrencyFraction >= 0))
  1265.                     {
  1266.                         lCurrencyFraction = "0" + lCurrencyFraction;
  1267.                     }
  1268.                     
  1269.                     if (lCurrencyWhole >= 0)
  1270.                     {
  1271.                         if (aIsCurrencySeparatorAtEnd.indexOf("False") != -1)
  1272.                         {                        
  1273.                             aInputTextbox.value = aCurrencySymbol + lCurrencyWhole + aCurrencyDecimalSeparator + lCurrencyFraction;
  1274.                         }
  1275.                         else
  1276.                         {
  1277.                             aInputTextbox.value = lCurrencyWhole + aCurrencyDecimalSeparator + lCurrencyFraction + aCurrencySymbol;
  1278.                         }
  1279.                     }
  1280.                     else
  1281.                     {
  1282.                         if (aIsCurrencySeparatorAtEnd.indexOf("False") != -1)
  1283.                         {            
  1284.                             if (lParenthesesRepresentationOfNegativeValue == false)
  1285.                             {            
  1286.                                 aInputTextbox.value = "-" + aCurrencySymbol + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction;
  1287.                             }
  1288.                             else
  1289.                             {
  1290.                                 aInputTextbox.value = "(" + aCurrencySymbol + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction + ")";
  1291.                             }
  1292.                         }
  1293.                         else
  1294.                         {
  1295.                             if (lParenthesesRepresentationOfNegativeValue == false)
  1296.                             {            
  1297.                                 aInputTextbox.value = "-" + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction + aCurrencySymbol;
  1298.                             }
  1299.                             else
  1300.                             {
  1301.                                 aInputTextbox.value = "(" + Math.abs(lCurrencyWhole) + aCurrencyDecimalSeparator + lCurrencyFraction + aCurrencySymbol + ")";
  1302.                             }                        
  1303.                         }
  1304.                     }
  1305.                 }
  1306.             }
  1307.         }
  1308.     // }
  1309. }
  1310.  
  1311.  
  1312.  
  1313. /**************************************************************************************
  1314.  *  Function    : adjustInteger()                                                     *
  1315.  *  Description : onkeyup event handler to increment/decrement integer fields.        *
  1316.  *  Parameters  : aInputTextbox, html textbox containing the integer value to be      *
  1317.  *                    incremented/decremented                                         *
  1318.  *  ISD Feature : "Increment/Decrement Numerical Fields"                              *
  1319.  *  Authors     : Samson Wong                                                         *
  1320.  **************************************************************************************/
  1321. function adjustInteger(aInputTextbox, aKeyCode)
  1322. {
  1323.     // if (justDoIt == true)
  1324.     // {
  1325.         // var lWhichCode = event.keyCode;
  1326.         var lWhichCode = aKeyCode;
  1327.         
  1328.         // if up arrow, or plus key...
  1329.         if ((lWhichCode == 38) || (lWhichCode == 107))
  1330.         {
  1331.             // strip "+" character if it has been appended to integer value
  1332.             while ((lWhichCode == 107) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "+"))
  1333.             {
  1334.                 aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1);
  1335.             }
  1336.                 
  1337.             // if currency value not initialized or contains invalid characters...
  1338.             if ((aInputTextbox.value == "") || (isNaN(aInputTextbox.value)))
  1339.             {
  1340.                 // set initial value
  1341.                 aInputTextbox.value = "1";
  1342.             }
  1343.             else
  1344.             {
  1345.                 // myAlert("adjustInteger(aInputTextbox.value=" + aInputTextbox.value + ")");
  1346.                 aInputTextbox.value = new Number(aInputTextbox.value) + 1;
  1347.             }
  1348.         }
  1349.         // if down arrow, or minus key...
  1350.         else if ((lWhichCode == 40) || (lWhichCode == 109))
  1351.         {
  1352.             // strip "-" character if it has been appended to integer value
  1353.             while ((lWhichCode == 109) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "-"))
  1354.  
  1355.             {
  1356.                 aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1);
  1357.             }
  1358.     
  1359.             // if currency value not initialized or contains invalid characters...
  1360.             if ((aInputTextbox.value == "") || (isNaN(aInputTextbox.value)))
  1361.             {
  1362.                 // set initial value
  1363.                 aInputTextbox.value = "1";
  1364.             }
  1365.             else
  1366.             {
  1367.                 // myAlert("adjustInteger(aInputTextbox.value=" + aInputTextbox.value + ")");
  1368.                 aInputTextbox.value = new Number(aInputTextbox.value) - 1;
  1369.             }
  1370.         }
  1371.     // }
  1372. }
  1373.  
  1374.  
  1375. /**************************************************************************************
  1376.  *  Function    : createNewDate()                                                     *
  1377.  *  Description : Create and return a new date object based on the value in the       *
  1378.  *                    specified textbox and the current date pattern.                 *
  1379.  *  Parameters  : aInputTextbox, textbox containing the current date to be            *
  1380.  *                    incremented/decremented                                         *
  1381.  *  Assumptions : parseDatePattern() has already been called, so that the format      *
  1382.  *                    of the date is known.                                           *
  1383.  *  ISD Feature : "Increment/Decrement Numerical Fields"                              *
  1384.  *  Authors     : Samson Wong                                                         *
  1385.  **************************************************************************************/
  1386. function createNewDate(aInputTextbox)
  1387. {
  1388.     // myAlert("createNewDate(aInputTextbox.value=" + aInputTextbox.value + ")");
  1389.     
  1390.     var rNewDate = new Date();
  1391.     var lDateStringArray;
  1392.     
  1393.     if (gDateSeparator1 == gDateSeparator2)
  1394.     {
  1395.         lDateStringArray = (aInputTextbox.value).split(gDateSeparator1);
  1396.     }
  1397.     else // (gDateSeparator1 != gDateSeparator2)
  1398.     {
  1399.         var lTempArray1 = (aInputTextbox.value).split(gDateSeparator1);
  1400.         var lDatePortion1 = lTempArray1[0];
  1401.         var lTempArray2 = lTempArray1[1].split(gDateSeparator2);
  1402.         var lDatePortion2 = lTempArray2[0];
  1403.         if (lTempArray2.length == 1)
  1404.         {
  1405.             lDateStringArray = new Array(lDatePortion1, lDatePortion2);
  1406.         }
  1407.         else if (lTempArray2.length > 1)
  1408.         {
  1409.             lDateStringArray = new Array(lDatePortion1, lDatePortion2, lTempArray2[1]);
  1410.         }
  1411.     }
  1412.     
  1413.     if (gDatePatternArray != null)
  1414.     {
  1415.         if ((gDatePatternArray.length == 3) &&
  1416.             (gDatePatternArray[0].charAt(0) == "m") &&
  1417.             (gDatePatternArray[1].charAt(0) == "d") &&
  1418.             (gDatePatternArray[2].charAt(0) == "y")) {
  1419.                 rNewDate.setTime(Date.parse(aInputTextbox.value));
  1420.         }
  1421.         else if ((gDatePatternArray.length == 3) &&
  1422.             (gDatePatternArray[0].charAt(0) == "d") &&
  1423.             (gDatePatternArray[1].charAt(0) == "m") &&
  1424.             (gDatePatternArray[2].charAt(0) == "y")) {
  1425.                 // Date.parse expects date in mm/dd/yyyy format, so swap date and month portions if date pattern is dd/mm/yyyy
  1426.                 rNewDate.setTime(Date.parse(new String(lDateStringArray[1] + gDateSeparator1 + lDateStringArray[0] + gDateSeparator1 + lDateStringArray[2])));
  1427.         }        
  1428.         else {   
  1429.             for (var i=0; i<(gDatePatternArray.length); i++) {
  1430.                 switch(gDatePatternArray[i].charAt(0)) {
  1431.                     case "m":
  1432.                         // alert("createNewDate(lDateStringArrayM[" + i + "]=" + lDateStringArray[i] + ")");
  1433.                         // alert("createNewDate(lDateStringArrayM[" + i + "]-1=" + lDateStringArray[i]-1 + ")");
  1434.                         rNewDate.setMonth(lDateStringArray[i]-1);
  1435.                         break;
  1436.                     case "d":
  1437.                         // myAlert("createNewDate(lDateStringArrayD[" + i + "]=" + lDateStringArray[i] + ")");
  1438.                         rNewDate.setDate(lDateStringArray[i]);
  1439.                         break;
  1440.                     case "y":
  1441.                         // myAlert("createNewDate(lDateStringArrayY[" + i + "]=" + lDateStringArray[i] + ")");
  1442.                         // if year string is only two characters long...
  1443.                         if (lDateStringArray[i].length == 2)
  1444.                         {
  1445.                             // prepend default century
  1446.                             rNewDate.setYear("20" + lDateStringArray[i]);
  1447.                         }
  1448.                         else
  1449.                         {
  1450.                             rNewDate.setYear(lDateStringArray[i]);
  1451.                         }
  1452.                         break;
  1453.                 }
  1454.             }
  1455.         }
  1456.     }
  1457.  
  1458.     return (rNewDate);
  1459. }
  1460.  
  1461.  
  1462. /**************************************************************************************
  1463.  *  Function    : displayDate()                                                       *
  1464.  *  Description : Display a date in the specified textbox.                            *
  1465.  *  Parameters  : aInputTextbox, textbox into which to display date                   *
  1466.  *                aDate, date to be displayed in specified textbox                    *
  1467.  *  Assumptions : parseDatePattern() has already been called, so that the display     *
  1468.  *                    format of the date is known.                                    *
  1469.  *  ISD Feature : "Increment/Decrement Numerical Fields"                              *
  1470.  *  Authors     : Samson Wong                                                         *
  1471.  **************************************************************************************/
  1472. function displayDate(aInputTextbox, aDate)
  1473. {
  1474.     aInputTextbox.value = "";
  1475.     
  1476.     if (gDatePatternArray != null)
  1477.     {
  1478.         for (var i=0; i<(gDatePatternArray.length); i++) {
  1479.             switch(gDatePatternArray[i].charAt(0)) {
  1480.                 case "m":
  1481.                     // month pattern is two characters long, but the current month is
  1482.                     //     only a single digit...
  1483.                     if ((gDatePatternArray[i].length == 2) && (aDate.getMonth() < 9))
  1484.                     {
  1485.                         // prepend a "0" to month string
  1486.                         aInputTextbox.value += "0" + new String(aDate.getMonth()+1);
  1487.                     }
  1488.                     else
  1489.                     {
  1490.                         aInputTextbox.value += new String(aDate.getMonth()+1);
  1491.                     }
  1492.                     break;
  1493.                 case "d":
  1494.                     aInputTextbox.value += aDate.getDate();
  1495.                     break;
  1496.                 case "y":
  1497.                     var lDateYearString = new String(aDate.getFullYear());
  1498.                     // if (lDateYearString.length < 4)
  1499.                     if (aDate.getFullYear() < 1000)
  1500.                     {
  1501.                         // correct browser bug which returns "1xx" for the year "20xx"
  1502.                         aDate.setFullYear(aDate.getFullYear() + 1900);
  1503.                     }
  1504.                     aInputTextbox.value += aDate.getFullYear();
  1505.                     break;
  1506.             }
  1507.             
  1508.             // post-pend date separator except for last portion of date
  1509.             if (i == 0) {
  1510.                 aInputTextbox.value += gDateSeparator1;
  1511.             }
  1512.             else if ((i == 1) && (gDateDayPosition != 0)) {
  1513.                 aInputTextbox.value += gDateSeparator2;
  1514.             }
  1515.         }
  1516.     }
  1517. }
  1518.  
  1519.  
  1520. /**************************************************************************************
  1521.  *  Function    : printPage()                                                         *
  1522.  *  Description : Invokes the system's print program (to print the current page).     *
  1523.  *  ISD Feature : "Print Page"                                                        *
  1524.  *  Authors     : Samson Wong                                                         *
  1525.  **************************************************************************************/
  1526. function printPage()
  1527. {
  1528.     // if (justDoIt == true)
  1529.     // {
  1530.         window.print();
  1531.     // }
  1532. }
  1533.  
  1534.  
  1535. /**************************************************************************************
  1536.  *  Function    : emailPage()                                                         *
  1537.  *  Description : Invokes the system's default e-mail client to send an e-mail with   *
  1538.  *                    the current URL in the body of the message.                     *
  1539.  *  ISD Feature : "E-mail Page"                                                       *
  1540.  *  Authors     : Samson Wong                                                         *
  1541.  **************************************************************************************/
  1542. function emailPage()
  1543. {
  1544.     // if (justDoIt == true)
  1545.     // {
  1546.         var lMailStr;
  1547.         lMailStr = "mailto:?body=" + location.href; 
  1548.         location.href = lMailStr;
  1549.     // }
  1550. }
  1551.  
  1552.  
  1553. /**************************************************************************************
  1554.  *  Description : Global variables used by the following functions:                   * 
  1555.  *                    moveToNextTableRow()                                            *
  1556.  *                    moveToPreviousTableRow()                                        *
  1557.  *                    moveToThisTableRow()                                            *
  1558.  *                    updateCurrentTableAndIndex()                                    *
  1559.  *                    highlightTableRow()                                             *
  1560.  *                    clickEditButtonOfTableRowInFocus()                              *
  1561.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1562.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1563.  **************************************************************************************/
  1564. var justDoIt = true;
  1565. var currentTable = null;
  1566. var currentRow = null;
  1567. var currentRowIndex = 0;
  1568.  
  1569. /**************************************************************************************
  1570.  *  Function    : captureUpDownKey()                                                  *
  1571.  *  Description : Captures an "up/down arrow" and "enter" keyboard event, and calls   *
  1572.  *                    the respective function to process the event.                   *
  1573.  *  Parameters  : pTableInFocus, html table receiving the keyboard event              *
  1574.  *                event, browser-generated event object                               *
  1575.  *  Assumptions : Only table panels will call this function.                          *
  1576.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1577.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1578.  **************************************************************************************/
  1579. function captureUpDownKey(pTableInFocus, event) {
  1580.  
  1581.     // capture current scroll position for "maintain position in tables" feature 
  1582.     setCurrentBrowserCoordinates();
  1583.     
  1584.     if (justDoIt == true) {
  1585.         // if focus is not on a drop-down list, nor the page size entry field (otherwise
  1586.         // drop-down list navigation via up/down/enter keypress takes precedence)    
  1587.         if ((event.srcElement == null) || ((event.srcElement.nodeName != "SELECT") && ((event.srcElement.id).indexOf("PageSize") == -1))) {
  1588.         
  1589.             if (event.keyCode) {
  1590.             
  1591.                 // if key down...
  1592.                 if (event.keyCode == 40) {
  1593.                     event.returnValue = false;
  1594.                     event.cancel = true;
  1595.                     event.cancelBubble = true;
  1596.                     if (event.stopPropagation) event.stopPropagation();
  1597.                     moveToNextTableRow(pTableInFocus);
  1598.                 }
  1599.                 // if key up...
  1600.                 else if (event.keyCode == 38) {
  1601.                     event.returnValue = false;
  1602.                     event.cancel = true;
  1603.                     event.cancelBubble = true;
  1604.                     if (event.stopPropagation) event.stopPropagation();
  1605.                     moveToPreviousTableRow(pTableInFocus);
  1606.                 }
  1607.                 // if enter key...
  1608.                 else if (event.keyCode == 13) {
  1609.                     if (clickEditButtonOfTableRowInFocus() == true) {
  1610.                         event.returnValue = false;
  1611.                         event.cancel = true;
  1612.                          event.cancelBubble = true;
  1613.                         if (event.stopPropagation) event.stopPropagation();
  1614.                    }
  1615.                     // else let event bubble up to "enter key capture" code for the above column filter button
  1616.                 }
  1617.             }
  1618.         }
  1619.     }
  1620. }
  1621.  
  1622. /**************************************************************************************
  1623.  *  Function    : captureEnterKeyInScrollingTable()                                   *
  1624.  *  Description : Captures an "enter" keyboard event, and calls the respective        *
  1625.  *                    function to process the event.                                  *
  1626.  *  Parameters  : pTableInFocus, html table receiving the keyboard event              *
  1627.  *                event, browser-generated event object                               *
  1628.  *  Assumptions : Only scrolling table panels will call this function.                *
  1629.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1630.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1631.  **************************************************************************************/
  1632. function captureEnterKeyInScrollingTable(pTableInFocus, event) {
  1633.  
  1634.     // capture current scroll position for "maintain position in tables" feature 
  1635.     setCurrentBrowserCoordinates();
  1636.     
  1637.     if (justDoIt == true) {
  1638.             
  1639.         // for IE...
  1640.         if (event.keyCode) {
  1641.             // if enter key...
  1642.             if (event.keyCode == 13) {
  1643.                 if (clickEditButtonOfTableRowInFocus() == true) {
  1644.                     event.returnValue = false;
  1645.                     event.cancel = true;
  1646.                     event.cancelBubble = true;
  1647.                     if (event.stopPropagation) event.stopPropagation();
  1648.                 }
  1649.                 /* else let event bubble up to "enter key capture" code for the above column filter button */
  1650.             }
  1651.             // if key down...
  1652.             else if (event.keyCode == 40) {
  1653.                 event.returnValue = false;
  1654.                 event.cancel = true;
  1655.                 event.cancelBubble = true;
  1656.                 if (event.stopPropagation) event.stopPropagation();
  1657.                 // ignore because up/down keypress functionality is not supported in scrolling tables
  1658.             }
  1659.             // if key up...
  1660.             else if (event.keyCode == 38) {
  1661.                 event.returnValue = false;
  1662.                 event.cancel = true;
  1663.                 event.cancelBubble = true;
  1664.                 if (event.stopPropagation) event.stopPropagation();
  1665.                 // ignore because up/down keypress functionality is not supported in scrolling tables
  1666.             }
  1667.         }
  1668.         // if Netscape/Firefox...
  1669.         else if (event.which) {
  1670.         
  1671.             // if enter key...
  1672.             if (event.which == 13) {
  1673.                 if (clickEditButtonOfTableRowInFocus() == true) {
  1674.                     event.returnValue = false;
  1675.                     event.cancel = true;
  1676.                     event.cancelBubble = true;
  1677.                     if (event.stopPropagation) event.stopPropagation();
  1678.                 }
  1679.                 /* else let event bubble up to "enter key capture" code for the above column filter button */
  1680.             }
  1681.             // if key down...
  1682.             else if (event.which == 40) {
  1683.                 event.returnValue = false;
  1684.                 event.cancel = true;
  1685.                  event.cancelBubble = true;
  1686.                 if (event.stopPropagation) event.stopPropagation();
  1687.                // ignore because up/down keypress functionality is not supported in scrolling tables
  1688.             }
  1689.             // if key up...
  1690.             else if (event.which == 38) {
  1691.                 event.returnValue = false;
  1692.                 event.cancel = true;
  1693.                 event.cancelBubble = true;
  1694.                 if (event.stopPropagation) event.stopPropagation();
  1695.                 // ignore because up/down keypress functionality is not supported in scrolling tables
  1696.             }
  1697.         }
  1698.     }
  1699. }
  1700.  
  1701. /**************************************************************************************
  1702.  *  Function    : moveToNextTableRow()                                                *
  1703.  *  Description : Upon "down arrow" keypress, disables "up/down arrow navigation"     *
  1704.  *                    highlight color on the current table row, and enables same on   *
  1705.  *                    the next table row.                                             *
  1706.  *  Parameters  : pTableInFocus, html table receiving the "down arrow" keyboard event *
  1707.  *  Assumptions : None.                                                               *
  1708.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1709.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1710.  **************************************************************************************/
  1711. function moveToNextTableRow(pTableInFocus) {
  1712.     var tableInFocus;
  1713.     var tableRows;
  1714.     var maxRowIndex;
  1715.     var tableCells;
  1716.  
  1717.     if (justDoIt == true) {  
  1718.      
  1719.         if (pTableInFocus != null) {
  1720.         
  1721.             // if focus is still within same table...
  1722.             if (currentTable == pTableInFocus)
  1723.             {                    
  1724.                 // determine the number of rows (including "header row") in this table
  1725.                 var maxRowIndex = getNumberOfTableRows(pTableInFocus);
  1726.  
  1727.                 if (maxRowIndex > 0)
  1728.                 {                    
  1729.                     // if current row is not the last row of this table...
  1730.                     if ((currentRowIndex >= 0) && (currentRowIndex < maxRowIndex-1)) {
  1731.                     
  1732.                         if (tableRowHighlightable(getTableRow(currentRowIndex+1)) == true) {
  1733.  
  1734.                             // unhighlight the current row
  1735.                             unhighlightTableRow(currentRow);
  1736.                         
  1737.                             // make previous row of this table the current row
  1738.                             currentRowIndex++;
  1739.         
  1740.                             // highlight the (new) current row
  1741.                             highlightTableRow(getTableRow(currentRowIndex));
  1742.                         }   
  1743.                     }
  1744.                 }
  1745.             }
  1746.             else {
  1747.                 // make this new table in focus the current table
  1748.                 currentTable = pTableInFocus;
  1749.  
  1750.                 moveToNextTableRow(currentTable);
  1751.             }
  1752.         }
  1753.     }
  1754. }
  1755.  
  1756. /**************************************************************************************
  1757.  *  Function    : moveToPreviousTableRow()                                            *
  1758.  *  Description : Upon "up arrow" keypress, disables the "up/down arrow navigation"   *
  1759.  *                    highlight color on the current table row, and enables same on   *
  1760.  *                    the previous table row.                                         *
  1761.  *  Parameters  : pTableInFocus, html table receiving the "down arrow" keyboard event *
  1762.  *  Assumptions : None.                                                               *
  1763.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1764.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1765.  **************************************************************************************/
  1766. function moveToPreviousTableRow(pTableInFocus) {
  1767.  
  1768.     if (justDoIt == true)
  1769.     {
  1770.         if (pTableInFocus != null)
  1771.         {
  1772.             // if focus is still within same table...
  1773.             if (currentTable == pTableInFocus)
  1774.             {
  1775.                 // determine the number of rows (including "header row") in this table
  1776.                 var maxRowIndex = getNumberOfTableRows(pTableInFocus);
  1777.  
  1778.                 if (maxRowIndex > 0)
  1779.                 {                    
  1780.                     // if current row is not the first row of this table...
  1781.                     if ((currentRowIndex > 1) && (currentRowIndex < maxRowIndex))
  1782.                     {                    
  1783.                         if (tableRowHighlightable(getTableRow(currentRowIndex-1)) == true)
  1784.                         {    
  1785.                             // unhighlight the current row
  1786.                             unhighlightTableRow(currentRow);
  1787.                         
  1788.                             // make previous row of this table the current row
  1789.                             currentRowIndex--;
  1790.         
  1791.                             // highlight the (new) current row
  1792.                             highlightTableRow(getTableRow(currentRowIndex));
  1793.                         }   
  1794.                     }
  1795.                 }
  1796.             }
  1797.             else {
  1798.                 // make this new table in focus the current table
  1799.                 currentTable = pTableInFocus;
  1800.  
  1801.                 moveToPreviousTableRow(currentTable);
  1802.             }
  1803.         }
  1804.     }
  1805. }
  1806.  
  1807. /**************************************************************************************
  1808.  *  Function    : moveToThisTableRow()                                                *
  1809.  *  Description : Upon "radio button select", disables the "up/down arrow navigation" *
  1810.  *                    highlight color on the current table row, and enables same on   *
  1811.  *                    the newly selected table row.                                   *
  1812.  *  Parameters  : pTableCell, "radio button" table cell selected                      *
  1813.  *  Assumptions : Only "radio button" table cells will call this function.            *
  1814.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1815.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1816.  **************************************************************************************/
  1817. function moveToThisTableRow(pTableCell) {
  1818.     // capture current scroll position for "maintain position in tables" feature 
  1819.     setCurrentBrowserCoordinates();
  1820.     
  1821.     if (justDoIt == true) {
  1822.  
  1823.         if (pTableCell != null) {
  1824.  
  1825.             var tableRow = pTableCell.parentNode;
  1826.             
  1827.             if (tableRow.nodeName == "TD")
  1828.             {
  1829.                 tableRow = tableRow.parentNode;
  1830.             }
  1831.  
  1832.             if (tableRowHighlightable(tableRow) == true) {
  1833.             
  1834.                 var iconCellContents = tableRow.getElementsByTagName("input");
  1835.                 
  1836.                 for (var i=(iconCellContents.length-1); i>=0; i--)
  1837.                 {
  1838.                     if (iconCellContents[i].type == "checkbox")
  1839.                     {
  1840.                         iconCellContents[i].focus();
  1841.                         break;
  1842.                     }
  1843.                 }
  1844.                 
  1845.                 // if current row highlighted...
  1846.                 if (currentTable != null)
  1847.                 {
  1848.                     unhighlightTableRow(currentRow);
  1849.                 }
  1850.         
  1851.                 // determine current table and index resulting from focus change
  1852.                 updateCurrentTableAndIndex(tableRow);
  1853.                 
  1854.                 // highlight (new) current table row
  1855.                 highlightTableRow(tableRow);
  1856.             }
  1857.         }
  1858.     }
  1859. }
  1860.  
  1861.  
  1862. /**************************************************************************************
  1863.  *  Function    : getTableRow()                                                       *
  1864.  *  Description : Retrieve the table row specified by pTableRowIndex in the "current" *
  1865.  *                    table.                                                          *
  1866.  *  Parameters  : pTableRowIndex, index of table row to retrieve                      *
  1867.  *  Assumptions : Global "currentTable" points to a valid table.                      *
  1868.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1869.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1870.  **************************************************************************************/
  1871. function getTableRow(pTableRowIndex)
  1872. {
  1873.     var rTableRow = null;
  1874.     
  1875.     if (justDoIt == true)
  1876.     {
  1877.         if (currentTable != null)
  1878.         {
  1879.             var lTableRows = currentTable.getElementsByTagName("tr");
  1880.             var lTableRowIndex = 1;
  1881.             
  1882.             // if there are enough rows in the current table...
  1883.             if (pTableRowIndex < lTableRows.length)
  1884.             {
  1885.                 // while table row not found...
  1886.                 for (var i=1; i<lTableRows.length; i++)
  1887.                 {
  1888.                     // if table row is part of main table (i.e., not a nested table row)...
  1889.                     if (lTableRows[i].parentNode.parentNode == currentTable)
  1890.                     {
  1891.                         // if this is the specified table row index...
  1892.                         if (lTableRowIndex == pTableRowIndex)
  1893.                         {
  1894.                             // save a reference to this row
  1895.                             rTableRow = lTableRows[i];
  1896.                             break;
  1897.                         }
  1898.                         // else move on to the next table row in main table
  1899.                         else
  1900.                         {
  1901.                             lTableRowIndex++;
  1902.                         }
  1903.                     }
  1904.                 }
  1905.             }
  1906.         }
  1907.     }
  1908.     
  1909.     // alert("getTableRow(rTableIsNull=" + (rTableRow == null) + ",currentRowIndex=" + currentRowIndex + ",pTableRowIndex=" + pTableRowIndex + ")");
  1910.     return rTableRow;
  1911. }
  1912.  
  1913.  
  1914. /**************************************************************************************
  1915.  *  Function    : getNumberOfTableRows()                                              *
  1916.  *  Description : Returns the number of table rows in the specified main table.       *
  1917.  *  Parameters  : pTable, reference to table whose row count is to be returned        *
  1918.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1919.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1920.  **************************************************************************************/
  1921. function getNumberOfTableRows(pTable)
  1922. {
  1923.     var rNumberOfTableRows = 0;
  1924.     
  1925.     if (justDoIt == true)
  1926.     {
  1927.         if (pTable != null)
  1928.         {
  1929.             var lTableRows = pTable.getElementsByTagName("tr");
  1930.             
  1931.             for (var i=0; i<lTableRows.length; i++)
  1932.             {
  1933.                 // if table row is part of main table (i.e., not a nested table row)...
  1934.                 if (lTableRows[i].parentNode.parentNode == currentTable)
  1935.                 {
  1936.                     rNumberOfTableRows++;
  1937.                 }
  1938.             }
  1939.         }
  1940.     }
  1941.     
  1942.     // alert("getNumberOfTableRows(rNumberOfTableRows=" + rNumberOfTableRows + ")");
  1943.     return rNumberOfTableRows;
  1944. }
  1945.  
  1946.  
  1947. /**************************************************************************************
  1948.  *  Function    : updateCurrentTableAndIndex()                                        *
  1949.  *  Description : Updates the global variables, currentTable and currentRowIndex,     *
  1950.  *                    indicating the new table and row in focus.                      *
  1951.  *  Parameters  : pTableRow, new table row in focus                                   *
  1952.  *  Assumptions : pTableRow is a row in the current table.                            *
  1953.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  1954.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  1955.  **************************************************************************************/
  1956. function updateCurrentTableAndIndex(pTableRow) {
  1957.     var tableRows;
  1958.     var maxTableIndex;
  1959.  
  1960.     if (justDoIt == true) {
  1961.     
  1962.         // update current table
  1963.         currentTable = pTableRow.parentNode;
  1964.         currentRowIndex = 0;
  1965.  
  1966.         var lTableRows = currentTable.getElementsByTagName("tr");
  1967.         var lTableRowIndex = 1;
  1968.         
  1969.         for (var i=1; i<lTableRows.length; i++)
  1970.         {
  1971.             // if table row is part of main table (i.e., not a nested table row)...
  1972.             if (lTableRows[i].parentNode == currentTable)
  1973.             {
  1974.                 // if current table row found
  1975.                 if (lTableRows[i] == pTableRow)
  1976.                 {
  1977.                     // update current table row index
  1978.                     currentRowIndex = lTableRowIndex;
  1979.                     break;
  1980.                 }
  1981.                 // else move on to the next table row in main table
  1982.                 else
  1983.                 {
  1984.                     lTableRowIndex++;
  1985.                 }
  1986.             }
  1987.         }
  1988.         
  1989.         // alert("updateCurrentTableAndIndex(currentRowIndex=" + currentRowIndex + ")"); 
  1990.     }
  1991. }
  1992.  
  1993. /**************************************************************************************
  1994.  *  Function    : unhighlightTableRow()                                               *
  1995.  *  Description : For the specified table row, unchecks the "selection checkbox", and *
  1996.  *                    disables the "up/down arrow navigation" highlight color on its  *
  1997.  *                    table cells.                                                    *
  1998.  *  Parameters  : pTableRow, table row to be unhighlighted                            *
  1999.  *  Assumptions : None.                                                               *
  2000.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  2001.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  2002.  **************************************************************************************/
  2003. function unhighlightTableRow(pTableRow) {
  2004.  
  2005.     var iconCellContents = null;
  2006.  
  2007.     if (justDoIt == true) {
  2008.  
  2009.         if (pTableRow != null) {
  2010.  
  2011.             // retrieve all "input" items within table row
  2012.             iconCellContents = pTableRow.getElementsByTagName("input");
  2013.  
  2014.             var lCheckboxPresent = false;
  2015.             var lCheckboxChecked = false;
  2016.             if (iconCellContents != null)
  2017.             {
  2018.                 for (var i=0; i<=(iconCellContents.length-1); i++)
  2019.                 {
  2020.                     // if selection checkbox present within table row...
  2021.                     if ((iconCellContents[i].type == "checkbox") && (iconCellContents[i].id.indexOf("RecordRowSelection"))) {
  2022.                         lCheckboxPresent = true;
  2023.                         if (iconCellContents[i].checked == true)
  2024.                         {
  2025.                             lCheckboxChecked = true;
  2026.                         }
  2027.                         break;
  2028.                     }
  2029.                 }
  2030.             }
  2031.             
  2032.             if (lCheckboxPresent)
  2033.             {
  2034.                 if (lCheckboxChecked) {
  2035.                     // unhighlight row
  2036.                     tableCells = pTableRow.getElementsByTagName("td");
  2037.                     for (var i=0; i<tableCells.length; i++) {
  2038.                         if (tableCells[i].parentNode == pTableRow)
  2039.                         {
  2040.                             if ((tableCells[i].className == "tic") ||
  2041.                                 (tableCells[i].className == "tich") ||
  2042.                                 (tableCells[i].className == "icon_cell") ||
  2043.                                 (tableCells[i].className == "icon_cell_highlighted")) {
  2044.                                 tableCells[i].className = "tics";
  2045.                             }
  2046.                             else if ((tableCells[i].className == "ticnb") ||
  2047.                                 (tableCells[i].className == "tichnb")) {
  2048.                                 tableCells[i].className = "ticsnb";
  2049.                             }            
  2050.                             else if ((tableCells[i].className == "ticwb") ||
  2051.                                 (tableCells[i].className == "tichwb")) {
  2052.                                 tableCells[i].className = "ticswb";
  2053.                             }
  2054.                             else if ((tableCells[i].className == "tichb") ||
  2055.                                 (tableCells[i].className == "tichhb")) {
  2056.                                 tableCells[i].className = "ticshb";
  2057.                             }
  2058.                             else if ((tableCells[i].className == "ttc") ||
  2059.                                 (tableCells[i].className == "ttch") ||
  2060.                                 (tableCells[i].className == "table_cell") ||
  2061.                                 (tableCells[i].className == "table_cell_highlighted")) {
  2062.                                 tableCells[i].className = "ttcs";
  2063.                             }
  2064.                             else if ((tableCells[i].className == "tice") ||
  2065.                                 (tableCells[i].className == "tiche")) {
  2066.                                 tableCells[i].className = "ticse";
  2067.                             }
  2068.                             // alert("unhighlightTableRow(unhighlightingCheckedRow... currentRowIndex=" + currentRowIndex + ")");
  2069.                         }
  2070.                     }
  2071.                 }
  2072.                 else {
  2073.                     // unhighlight row
  2074.                     tableCells = pTableRow.getElementsByTagName("td");
  2075.                     for (var i=0; i<tableCells.length; i++) {
  2076.                         if (tableCells[i].parentNode == pTableRow)
  2077.                         {
  2078.                             if ((tableCells[i].className == "tics") ||
  2079.                                 (tableCells[i].className == "tich") ||
  2080.                                 (tableCells[i].className == "icon_cell_selected") ||
  2081.                                 (tableCells[i].className == "icon_cell_highlighted")) {
  2082.                                 tableCells[i].className = "tic";
  2083.                             }
  2084.                             else if ((tableCells[i].className == "ticsnb") ||
  2085.                                 (tableCells[i].className == "tichnb")) {
  2086.                                 tableCells[i].className = "ticnb";
  2087.                             }    
  2088.                             else if ((tableCells[i].className == "ticswb") ||
  2089.                                 (tableCells[i].className == "tichwb")) {
  2090.                                 tableCells[i].className = "ticwb";
  2091.                             }    
  2092.                             else if ((tableCells[i].className == "ticshb") ||
  2093.                                 (tableCells[i].className == "tichhb")) {
  2094.                                 tableCells[i].className = "tichb";
  2095.                             }    
  2096.                             else if ((tableCells[i].className == "ttcs") ||
  2097.                                      (tableCells[i].className == "ttch") ||
  2098.                                      (tableCells[i].className == "table_cell_selected") ||
  2099.                                      (tableCells[i].className == "table_cell_highlighted")) {
  2100.                                 tableCells[i].className = "ttc";
  2101.                             }
  2102.                             else if ((tableCells[i].className == "ticse") ||
  2103.                                      (tableCells[i].className == "tiche")) {
  2104.                                 tableCells[i].className = "tice";
  2105.                             }
  2106.                             // alert("unhighlightTableRow(unhighlightingUncheckedRow... currentRowIndex=" + currentRowIndex + ")");
  2107.                         }
  2108.                     }
  2109.                 
  2110.                 }
  2111.                 
  2112.                 // alert("unhighlightTableRow(currentRowIndex=" + currentRowIndex + ")");
  2113.             }
  2114.             // otherwise, disable table row unhighlighting
  2115.         }
  2116.     }
  2117. }
  2118.  
  2119.  
  2120. /**************************************************************************************
  2121.  *  Function    : highlightTableRow()                                                 *
  2122.  *  Description : For the specified table row, checks the "selection checkbox", and   *
  2123.  *                    enables the "up/down arrow navigation" highlight color on its   *
  2124.  *                    table cells.                                                    *
  2125.  *  Parameters  : pTableRow, table row to be highlighted                              *
  2126.  *  Assumptions : None.                                                               *
  2127.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  2128.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  2129.  **************************************************************************************/
  2130. function highlightTableRow(pTableRow) {
  2131.  
  2132.     var iconCellContents = null;
  2133.     
  2134.     if (justDoIt == true) {
  2135.  
  2136.         if (pTableRow != null) {
  2137.  
  2138.             // retrieve all "input" items within table row
  2139.             iconCellContents = pTableRow.getElementsByTagName("input");
  2140.             
  2141.             var lCheckboxPresent = false;
  2142.             if (iconCellContents != null)
  2143.             {
  2144.                 for (var i=0; i<=(iconCellContents.length-1); i++)
  2145.                 {
  2146.                     // if selection checkbox present within table row...
  2147.                     if ((iconCellContents[i].type == "checkbox") && (iconCellContents[i].id.indexOf("RecordRowSelection"))) {
  2148.                         lCheckboxPresent = true;
  2149.                         iconCellContents[i].focus();
  2150.                         break;
  2151.                         }
  2152.                 }
  2153.             }
  2154.             
  2155.             if (lCheckboxPresent)
  2156.             {
  2157.                 // highlight row
  2158.                 tableCells = pTableRow.getElementsByTagName("td");
  2159.                 for (var i=0; i<tableCells.length; i++) {
  2160.                     if (tableCells[i].parentNode == pTableRow)
  2161.                     {
  2162.                         if ((tableCells[i].className == "tic") ||
  2163.                             (tableCells[i].className == "tics") ||
  2164.                             (tableCells[i].className == "icon_cell") ||
  2165.                             (tableCells[i].className == "icon_cell_selected")){
  2166.                             tableCells[i].className = "tich";
  2167.                         }
  2168.                         else if ((tableCells[i].className == "ticnb") ||
  2169.                                 (tableCells[i].className == "ticsnb")) {
  2170.                             tableCells[i].className = "tichnb";
  2171.                         }    
  2172.                         else if ((tableCells[i].className == "ticwb") ||
  2173.                                 (tableCells[i].className == "ticswb")) {
  2174.                             tableCells[i].className = "tichwb";
  2175.                         }    
  2176.                         else if ((tableCells[i].className == "tichb") ||
  2177.                                 (tableCells[i].className == "ticshb")) {
  2178.                             tableCells[i].className = "tichhb";
  2179.                         }    
  2180.                         else if ((tableCells[i].className == "ttc") ||
  2181.                                  (tableCells[i].className == "ttcs") ||
  2182.                                  (tableCells[i].className == "table_cell") ||
  2183.                                  (tableCells[i].className == "table_cell_selected")) {
  2184.                             tableCells[i].className = "ttch";
  2185.                         }
  2186.                         else if ((tableCells[i].className == "tice") ||
  2187.                                  (tableCells[i].className == "ticse")) {
  2188.                             tableCells[i].className = "tiche";
  2189.                         }
  2190.                         
  2191.                         // save reference to current highlighted row
  2192.                         currentRow = pTableRow;
  2193.                     }
  2194.                 }
  2195.             
  2196.                 // alert("highlightTableRow(currentRowIndex=" + currentRowIndex + ",currentRowIsNull=" + (currentRow == null) + ")");
  2197.             }
  2198.         }
  2199.     }
  2200. }
  2201.  
  2202. /**************************************************************************************
  2203.  *  Function    : tableRowHighlightable()                                             *
  2204.  *  Description : Returns whether the table row contains a "selection checkbox".      *
  2205.  *  Parameters  : None.                                                               *
  2206.  *  Assumptions : None.                                                               *                 
  2207.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  2208.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  2209.  **************************************************************************************/
  2210. function tableRowHighlightable(pTableRow) {
  2211.  
  2212.     var rTableRowHighlightable = false;
  2213.     var iconCellContents = null;
  2214.     var headerCellContents = null;
  2215.     var tableRows = null;
  2216.     
  2217.     // retrieve all "input" items within table row
  2218.     iconCellContents = pTableRow.getElementsByTagName("input");
  2219.  
  2220.     var lCheckboxNode = null;
  2221.     if (iconCellContents != null)
  2222.     {
  2223.         for (var i=0; i<=(iconCellContents.length-1); i++)
  2224.         {
  2225.             // if selection checkbox present within table row...
  2226.             if ((iconCellContents[i].type == "checkbox") && (iconCellContents[i].id.indexOf("RecordRowSelection") != -1)) {
  2227.                 lCheckboxNode = iconCellContents[i];
  2228.                 break;
  2229.             }
  2230.         }
  2231.     }
  2232.     
  2233.     if (lCheckboxNode != null)
  2234.     {
  2235.         rTableRowHighlightable = true;
  2236.     }
  2237.     
  2238.     return(rTableRowHighlightable);
  2239. }
  2240.  
  2241. /**************************************************************************************
  2242.  *  Function    : clickEditButtonOfTableRowInFocus()                                  *
  2243.  *  Description : Invokes the edit record page of the selected record (in focus table *
  2244.  *                    row) by programmatically clicking the record's edit button.     *
  2245.  *  Parameters  : None.                                                               *
  2246.  *  Assumptions : The edit button is contained in the first cell of the table row in  *
  2247.  *                    focus.                                                          *                 
  2248.  *  ISD Feature : "Up/Down Arrow Keypress Navigation"                                 *
  2249.  *  Authors     : Samson Wong & Cocosoft B.V.                                         *
  2250.  **************************************************************************************/
  2251. function clickEditButtonOfTableRowInFocus() {
  2252.     var iconCellContents = null;
  2253.     var rTableRowClickable = false;
  2254.  
  2255.     if (justDoIt == true) {
  2256.     
  2257.         if (currentTable != null) {
  2258.         
  2259.             if (currentRow != null) {
  2260.             
  2261.                 iconCellContents = currentRow.getElementsByTagName("input");
  2262.                 
  2263.                 for (var i=0; i<iconCellContents.length; i++)
  2264.                 {
  2265.                     // alert("clickEditButtonOfTableRowInFocus(iconCellContents.item(" + i + ").id=" + iconCellContents[i].id + ")");
  2266.                     if (iconCellContents[i].id.indexOf("EditButton") != -1)
  2267.                     {
  2268.                         iconCellContents[i].click();
  2269.                         rTableRowClickable = true;
  2270.                         break;
  2271.                     }
  2272.                 }
  2273.             }
  2274.         }
  2275.     }
  2276.     
  2277.     return(rTableRowClickable);
  2278. }
  2279.  
  2280.  
  2281. /**************************************************************************************
  2282.  *  Function    : isChildSelectionCheckboxOf()                                        *
  2283.  *  Description : Determines whether selection checkbox is an immediate child         *
  2284.  *                    checkbox of the current parent table.                           *
  2285.  *  Parameters  : aParentTable, current parent table.                                 *
  2286.  *                aCheckbox, selection checkbox                                       *
  2287.  *  Assumptions : None.                                                               *
  2288.  *  ISD Feature : "Toggle All Checkboxes"                                             *
  2289.  *  Author      : Samson Wong                                                         *
  2290.  **************************************************************************************/
  2291. function isChildSelectionCheckboxOf(aParentTable, aCheckbox) {
  2292.     var lParentNode = aCheckbox.parentNode;
  2293.     while (lParentNode.nodeName != "TABLE") {
  2294.         lParentNode = lParentNode.parentNode;
  2295.     }
  2296.     
  2297.     return(aParentTable == lParentNode);
  2298. }
  2299.  
  2300.  
  2301. /**************************************************************************************
  2302.  *  Function    : toggleAllCheckboxes()                                               *
  2303.  *  Description : Checks/unchecks all "icon cell" checkboxes (and highlights/         *
  2304.  *                    unhighlights their corresponding rows) if the "select all"      *
  2305.  *                    checkbox is checked/unchecked.                                  *
  2306.  *  Parameters  : aMainCheckboxNode, reference to "select all" checkbox.              *
  2307.  *  Assumptions : This onclick event handler should only be used by the "select all"  *
  2308.  *                    checkbox.                                                       *
  2309.  *  ISD Feature : "Select All Checkbox"                                               *
  2310.  *  Author      : Samson Wong                                                         *
  2311.  **************************************************************************************/
  2312. function toggleAllCheckboxes(aMainCheckboxNode) {
  2313.  
  2314.     var lTableNode = aMainCheckboxNode;  
  2315.     
  2316.     // find parent table
  2317.     while (lTableNode.nodeName != "TABLE") {
  2318.         lTableNode = lTableNode.parentNode;
  2319.     }
  2320.     
  2321.     // retrieve all "input" items within parent table    
  2322.     var lInputArray = lTableNode.getElementsByTagName("input");
  2323.     
  2324.     // if ToggleAllCheckbox has been checked...
  2325.     if (aMainCheckboxNode.checked == true) {
  2326.  
  2327.         for (i=0; i<lInputArray.length; i++) {
  2328.  
  2329.             // if immediate child selection checkbox or another ToggleAllCheckbox present within table row...
  2330.             if (isChildSelectionCheckboxOf(lTableNode, lInputArray[i])) {
  2331.                 if ((lInputArray[i].type == "checkbox") &&
  2332.                     ((lInputArray[i].id.indexOf("RecordRowSelection") != -1) || (lInputArray[i].id.indexOf("ToggleAll") != -1))) {
  2333.                         // check immediate child checkbox
  2334.                         lInputArray[i].checked = true;
  2335.                         selectTableRow(lInputArray[i].parentNode.parentNode);
  2336.                  }
  2337.             }
  2338.         }
  2339.     }
  2340.     // if ToggleAllCheckbox has been unchecked...
  2341.     else {
  2342.  
  2343.         for (i=0; i<lInputArray.length; i++) {
  2344.              
  2345.             // if immediate child selection checkbox or another ToggleAllCheckbox present within table row...            
  2346.             if (isChildSelectionCheckboxOf(lTableNode, lInputArray[i])) {
  2347.                 if ((lInputArray[i].type == "checkbox") &&
  2348.                     ((lInputArray[i].id.indexOf("RecordRowSelection") != -1) || (lInputArray[i].id.indexOf("ToggleAll") != -1))) {
  2349.                         // uncheck immediate child checkbox
  2350.                         lInputArray[i].checked = false;
  2351.                         unselectTableRow(lInputArray[i].parentNode.parentNode);
  2352.                  }
  2353.             }
  2354.         }
  2355.     }
  2356. }
  2357.  
  2358.  
  2359. /**************************************************************************************
  2360.  *  Function    : unselectTableRow()                                                  *
  2361.  *  Description : Disables "select" highlight color on the specified table row.       *
  2362.  *  Parameters  : aTableRow, reference to table row whose "select" highlight color is *
  2363.  *                    to be disabled.                                                 *
  2364.  *  ISD Feature : "Select All Checkbox"                                               *
  2365.  *  Author      : Samson Wong                                                         *
  2366.  **************************************************************************************/
  2367. function unselectTableRow(aTableRow) {
  2368.  
  2369.     if (justDoIt == true) {
  2370.  
  2371.         if (aTableRow != null) {
  2372.  
  2373.             // unselect row
  2374.             tableCells = aTableRow.getElementsByTagName("td");
  2375.             for (var i=0; i<tableCells.length; i++) {
  2376.             
  2377.                 // if table row cell in main table (i.e., not a nested table row cell)...
  2378.                 if (tableCells[i].parentNode == aTableRow)
  2379.                 {
  2380.                     if ((tableCells[i].className == "tics") ||
  2381.                         (tableCells[i].className == "icon_cell_selected")) {
  2382.                         tableCells[i].className = "tic";
  2383.                     }
  2384.                     else if (tableCells[i].className == "ticsnb") {
  2385.                         tableCells[i].className = "ticnb";
  2386.                     }    
  2387.                     else if (tableCells[i].className == "ticswb") {
  2388.                         tableCells[i].className = "ticwb";
  2389.                     }                        
  2390.                     else if ((tableCells[i].className == "ttcs") ||
  2391.                              (tableCells[i].className == "table_cell_selected")) {
  2392.                         tableCells[i].className = "ttc";
  2393.                     }
  2394.                     else if (tableCells[i].className == "ticse") {
  2395.                         tableCells[i].className = "tice";
  2396.                     }
  2397.                     // alert("unselectTableRow(unselecting... tableCells.item(" + i + ").nodeName=" + tableCells[i].nodeName + ")");
  2398.                 }
  2399.             }
  2400.         }
  2401.     }
  2402. }
  2403.  
  2404.  
  2405. /**************************************************************************************
  2406.  *  Function    : selectTableRow()                                                    *
  2407.  *  Description : Enables "select" highlight color on the specified table row.        *
  2408.  *  Parameters  : aTableRow, reference to table row whose "select" highlight color is *
  2409.  *                    to be enabled.                                                  *
  2410.  *  ISD Feature : "Select All Checkbox"                                               *
  2411.  *  Author      : Samson Wong                                                         *
  2412.  **************************************************************************************/
  2413. function selectTableRow(aTableRow) {
  2414.  
  2415.     if (justDoIt == true) {
  2416.  
  2417.         if (aTableRow != null) {
  2418.  
  2419.             // select row
  2420.             tableCells = aTableRow.getElementsByTagName("td");
  2421.             for (var i=0; i<tableCells.length; i++) {
  2422.  
  2423.                    // if table row cell in main table (i.e., not a nested table row cell)...
  2424.                 if (tableCells[i].parentNode == aTableRow)
  2425.                 {
  2426.                     if ((tableCells[i].className == "tic") ||
  2427.                         (tableCells[i].className == "icon_cell")) {
  2428.                         tableCells[i].className = "tics";
  2429.                     }
  2430.                     else if (tableCells[i].className == "ticnb") {
  2431.                         tableCells[i].className = "ticsnb";
  2432.                     }
  2433.                     else if (tableCells[i].className == "ticwb") {
  2434.                         tableCells[i].className = "ticswb";
  2435.                     }
  2436.                     else if ((tableCells[i].className == "ttc") ||
  2437.                              (tableCells[i].className == "table_cell")) {
  2438.                         tableCells[i].className = "ttcs";
  2439.                     }
  2440.                     else if (tableCells[i].className == "tice") {
  2441.                         tableCells[i].className = "ticse";
  2442.                     }
  2443.                     // alert("selectTableRow(selecting... tableCells.item(" + i + ").nodeName=" + tableCells[i].nodeName + ")");
  2444.                 }
  2445.             }
  2446.         }
  2447.     }
  2448. }
  2449.  
  2450.  
  2451. /**************************************************************************************
  2452.  *  Function    : setCurrentBrowserCoordinates()                                      *
  2453.  *  Description : Records current browser focus location based upon user input        *
  2454.  *                    (scroll, click, or keypress).                                   *
  2455.  *  Parameters  : None.                                                               *
  2456.  *  ISD Feature : "Maintain position in tables"                                       *
  2457.  *  Authors     : Akesh Gupta, Light Speed Solutions                                  *
  2458.  **************************************************************************************/
  2459.  function setCurrentBrowserCoordinates() {
  2460.     var scrollX, scrollY;
  2461.     
  2462.     // if (justDoIt == true) {
  2463.         var pageLeftCoordinate = document.getElementById("pageLeftCoordinate");
  2464.         var pageTopCoordinate = document.getElementById("pageTopCoordinate");
  2465.  
  2466.         // do not scroll in pre-v3.2.1 apps (which do not contain the hidden scroll coordinates fields)         
  2467.         if (!pageLeftCoordinate || !pageTopCoordinate) return;
  2468.     
  2469.         if (document.all)
  2470.         {
  2471.             if (!document.documentElement.scrollLeft)
  2472.                 scrollX = document.body.scrollLeft;
  2473.             else
  2474.                 scrollX = document.documentElement.scrollLeft;
  2475.          
  2476.             if (!document.documentElement.scrollTop)
  2477.                 scrollY = document.body.scrollTop;
  2478.             else
  2479.                 scrollY = document.documentElement.scrollTop;
  2480.         }
  2481.         else
  2482.         {
  2483.             scrollX = window.pageXOffset;
  2484.             scrollY = window.pageYOffset;
  2485.         }
  2486.             
  2487.         // alert("setCurrentBrowserCoordinates(x=" + scrollX + ",y=" + scrollY + ")");
  2488.         pageLeftCoordinate.value = scrollX;
  2489.         pageTopCoordinate.value = scrollY;
  2490.     // }
  2491. }
  2492.   
  2493. /**************************************************************************************
  2494.  *  Function    : goToCurrentBrowserCoordinates()                                     *
  2495.  *  Description : Moves to the browser coordinates previously saved by                *
  2496.  *                    setCurrentBrowserCoordinates().                                 *
  2497.  *  Parameters  : None.                                                               *
  2498.  *  ISD Feature : "Maintain position in tables"                                       *
  2499.  *  Authors     : Akesh Gupta, Light Speed Solutions                                  *
  2500.  **************************************************************************************/
  2501.  function goToCurrentBrowserCoordinates() {
  2502.     // if (justDoIt == true) {
  2503.         var pageLeftCoordinate = document.getElementById("pageLeftCoordinate");
  2504.         var pageTopCoordinate = document.getElementById("pageTopCoordinate");
  2505.  
  2506.         // do not scroll in pre-v3.2.1 apps (which do not contain the hidden scroll coordinates fields) 
  2507.         if (!pageLeftCoordinate || !pageTopCoordinate) return;
  2508.         
  2509.         // do not scroll if not a doPostBack() reload of page
  2510.         if ((pageLeftCoordinate.value == "") && (pageTopCoordinate.value == "")) return;
  2511.  
  2512.         var scrollX = pageLeftCoordinate.value;
  2513.         var scrollY = pageTopCoordinate.value;
  2514.         // alert("goToCurrentBrowserCoordinates(x=" + scrollX + ",y=" + scrollY + ")");
  2515.         window.scrollTo(scrollX, scrollY);
  2516.     // }
  2517.  }
  2518.  
  2519. /**************************************************************************************
  2520.  *  Function    : dropDownListTypeAhead()                                             *
  2521.  *  Description : Moves focus to select option which matches string entered on        *
  2522.  *                    keyboard.                                                       *
  2523.  *  Parameters  : dropdownlist, select element catching the keypress events.          *
  2524.  *                caseSensitive, indicates whether or not keypresses and select       *
  2525.  *                    option values need to match by case.                            *
  2526.  *  ISD Feature : "Dropdown List Type Ahead"                                          *
  2527.  *  Authors     : Akesh Gupta & Samson Wong                                           *
  2528.  **************************************************************************************/
  2529. function dropDownListTypeAhead(dropdownlist,caseSensitive) {
  2530.  
  2531.     // if (justDoIt == true) {
  2532.         // Make sure the control is a drop down list.
  2533.         if (dropdownlist.type != 'select-one') return;
  2534.     
  2535.         // check the keypressBuffer attribute is defined on the dropdownlist
  2536.         var undefined;
  2537.         
  2538.         // if enter key captured...
  2539.         if ((window.event) && (window.event.keyCode == 13))
  2540.         {
  2541.             // explicitly perform filtering
  2542.             setTimeout("__doPostBack('" + window.event.srcElement.id + "','')", 0);
  2543.         }
  2544.         
  2545.         window.event.cancelBubble = true;
  2546.     
  2547.         if (dropdownlist.keypressBuffer == undefined) {
  2548.             dropdownlist.keypressBuffer = "";
  2549.         } 
  2550.     
  2551.         // get the key that was pressed
  2552.         var key;
  2553.         
  2554.         if (event.keyCode) {        
  2555.             key = String.fromCharCode(window.event.keyCode);
  2556.         }
  2557.         else if (event.which) {
  2558.             key = String.fromCharCode(event.which);
  2559.         }
  2560.         
  2561.         dropdownlist.keypressBuffer += key;
  2562.  
  2563.         if (!caseSensitive) {
  2564.             // convert buffer to lowercase"
  2565.             dropdownlist.keypressBuffer = dropdownlist.keypressBuffer.toLowerCase();
  2566.         }
  2567.     
  2568.         // find if it is the start of any of the options
  2569.         var optionsLength = dropdownlist.options.length;
  2570.         
  2571.         for (var n=0; n < optionsLength; n++) {
  2572.             var optionText = dropdownlist.options[n].text;
  2573.             if (!caseSensitive) {
  2574.                 optionText = optionText.toLowerCase();
  2575.             }
  2576.             if (optionText.indexOf(dropdownlist.keypressBuffer,0) == 0) {
  2577.                 dropdownlist.selectedIndex = n;
  2578.                 
  2579.                 // if (dropdownlist.keypressBuffer.length > 1) {
  2580.                 //  alert("dropDownListTypeAhead(match, keypressBuffer=" + dropdownlist.keypressBuffer + ",selectedIndex=" + dropdownlist.selectedIndex + ")");
  2581.                 // }
  2582.  
  2583.                 // cancel the default behavior since we have selected our own value
  2584.                 window.event.returnValue = false;
  2585.                 return false;
  2586.             }
  2587.         }
  2588.     
  2589.         // alert("dropDownListTypeAhead(reset, keypressBuffer=" + dropdownlist.keypressBuffer + ")");
  2590.         
  2591.         // reset initial key to be inline with default behavior
  2592.         dropdownlist.keypressBuffer = key;
  2593.     // }
  2594.  
  2595.     // give default behavior
  2596.     return true;
  2597. }
  2598.  
  2599. /**************************************************************************************
  2600.  *  Description : Event handlers (scroll, click, and keypress) active for all pages.  *
  2601.  *  Parameters  : None.                                                               *
  2602.  *  ISD Feature : "Maintain position in tables"                                       *
  2603.  *  Authors     : Akesh Gupta, Light Speed Solutions                                  *
  2604.  **************************************************************************************/
  2605.   window.onload = goToCurrentBrowserCoordinates;
  2606.   window.onscroll = setCurrentBrowserCoordinates;
  2607.   window.onclick = setCurrentBrowserCoordinates;
  2608.   window.onkeypress = setCurrentBrowserCoordinates;  
  2609.  
  2610.  
  2611.  
  2612.  
  2613. /**************************************************************************************
  2614.  *  Description : Global variables used by "Detail Rollever Popup" feature.           *
  2615.  *  ISD Feature : "Detail Rollover Popup"                                             *
  2616.  *  Author      : Samson Wong                                                         *
  2617.  **************************************************************************************/
  2618. var gDisplayInnerHTML = 0;
  2619. var gPersist = false;
  2620. var gPopupTimer = null;
  2621. var gCurrentInnerHTML = '';
  2622. var gRTL = false;
  2623.  
  2624. // dummy "content" to be displayed in popup (for demo purposes only)
  2625. var gTitle = "Lorem Ipsum (2006)";
  2626. var gInnerHTML0 = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.';
  2627. var gInnerHTML1 = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.<br><br>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.';
  2628. var gInnerHTML2 = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.<br><br>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.<br><br>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.';
  2629. var gInnerHTML3 = '<!-- Begin Table Panel.html --><table class="dialog_view" cellpadding="0" cellspacing="0" border="0"><tr><td class="dialog_header"><table cellpadding="0" cellspacing="0" width="100%" border="0"><tr><td class="dialogHeaderEdgeL"><img src="../Images/space.gif" alt=""/></td><td class="dialogHeaderExpandCollapseIcon" valign="middle"><a onclick="toggleExpandCollapse(this);"><img id="ExpandCollapseIcon" src="../Images/DialogHeaderIconCollapse.gif" border="0" alt="Collapse panel"/></a></td><td class="dialogHeaderIcon"><img id="CategoriesTableIcon" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="dialog_header_text" valign="middle">Categories</td><td class="dialogHeaderTotalRecordCount"><table id="CollapsibleRegionTotalRecords" style="display:none;" cellspacing="0" cellpadding="0" border="0"><tr><td class="dialogHeaderTotalRecordCountText"><span id="CategoriesTotalItems">8</span></td></tr></table></td><td class="dialogHeaderEdgeR"><img src="../Images/space.gif" alt=""/></td></tr></table></td></tr><tr><td class="dialog_body"><table id="CollapsibleRegion" style="display:;" cellspacing="0" cellpadding="0" border="0"><tr><td><table cellpadding="0" cellspacing="3" border="0"><!-- Search & Filter Area --><tr><td class="filter_area">Search for</td><td><span><input name="CategoriesSearchArea" type="text" id="CategoriesSearchArea" class="Search_Input" CaseSensitive="False" Fields="CategoryName" FilterOperator="Contains" /></span></td><td class="filter_button_cell"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button-TL-white"><img src="../Images/space.gif" height="5" width="17" alt=""/></td><td class="button-T-white"><img src="../Images/space.gif" height="5" width="4" alt=""/></td><td class="button-TR-white"><img src="../Images/space.gif" height="5" width="16" alt=""/></td></tr><tr><td class="button-L-white"><img src="../Images/space.gif" height="14" width="17" alt=""/></td><td class="button-white"><a id="CategoriesSearchButton__Button" class="button_link" href="">Go</a></td><td class="button-R-white"><img src="../Images/space.gif" height="14" width="16" alt=""/></td></tr><tr><td class="button-BL-white"><img src="../Images/space.gif" height="8" width="17" alt=""/></td><td class="button-B-white"><img src="../Images/space.gif" height="8" width="4" alt=""/></td><td class="button-BR-white"><img src="../Images/space.gif" height="8" width="16" alt=""/></td></tr></table></td></tr><tr><td></td><td></td><td rowspan="100" class="filter_button_cell"></td> </tr><tr><td class="filter_area">Category Name</td><td><select name="CategoryNameFilter" onchange="" id="CategoryNameFilter" class="Filter_Input" FilterOperator="="><option selected="selected" value="--ANY--">All</option><option value="Beverages">Beverages</option><option value="Condiments">Condiments</option><option value="Confections">Confections</option><option value="Dairy Products">Dairy Products</option><option value="Grains/Cereals">Grains/Cereals</option><option value="Meat/Poultry">Meat/Poultry</option><option value="Produce">Produce</option><option value="Seafood">Seafood</option></select></td></tr></table><div class="spacer"></div><!-- Category Area --><table cellspacing="0" cellpadding="0" border="0"><tr><td><table cellspacing="0" cellpadding="0" border="0"><tr><td><table class="table_view" cellpadding="0" cellspacing="0" border="0" width="100%"><tr><!-- Pagination Area --><td class="pagination_row" colspan="100"><table cellspacing="0" cellpadding="0" border="0"><tr><td class="paginationRowEdgeL"><img src="../Images/space.gif" alt=""/></td><td class="button_bar_cell"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button-TL-white"><img src="../Images/space.gif" height="5" width="17" alt=""/></td><td class="button-T-white"><img src="../Images/space.gif" height="5" width="4" alt=""/></td><td class="button-TR-white"><img src="../Images/space.gif" height="5" width="16" alt=""/></td></tr><tr><td class="button-L-white"><img src="../Images/space.gif" height="14" width="17" alt=""/></td><td class="button-white"><a id="CategoriesNewButton__Button" class="button_link" href="">New</a></td><td class="button-R-white"><img src="../Images/space.gif" height="14" width="16" alt=""/></td></tr><tr><td class="button-BL-white"><img src="../Images/space.gif" height="8" width="17" alt=""/></td><td class="button-B-white"><img src="../Images/space.gif" height="8" width="4" alt=""/></td><td class="button-BR-white"><img src="../Images/space.gif" height="8" width="16" alt=""/></td></tr></table></td><td class="button_bar_cell"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button-TL-white"><img src="../Images/space.gif" height="5" width="17" alt=""/></td><td class="button-T-white"><img src="../Images/space.gif" height="5" width="4" alt=""/></td><td class="button-TR-white"><img src="../Images/space.gif" height="5" width="16" alt=""/></td></tr><tr><td class="button-L-white"><img src="../Images/space.gif" height="14" width="17" alt=""/></td><td class="button-white"><a id="CategoriesEditButton__Button" class="button_link" href="">Edit</a></td><td class="button-R-white"><img src="../Images/space.gif" height="14" width="16" alt=""/></td></tr><tr><td class="button-BL-white"><img src="../Images/space.gif" height="8" width="17" alt=""/></td><td class="button-B-white"><img src="../Images/space.gif" height="8" width="4" alt=""/></td><td class="button-BR-white"><img src="../Images/space.gif" height="8" width="16" alt=""/></td></tr></table></td><td class="button_bar_cell"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button-TL-white"><img src="../Images/space.gif" height="5" width="17" alt=""/></td><td class="button-T-white"><img src="../Images/space.gif" height="5" width="4" alt=""/></td><td class="button-TR-white"><img src="../Images/space.gif" height="5" width="16" alt=""/></td></tr><tr><td class="button-L-white"><img src="../Images/space.gif" height="14" width="17" alt=""/></td><td class="button-white"><a id="CategoriesDeleteButton__Button" class="button_link" href="">Delete</a></td><td class="button-R-white"><img src="../Images/space.gif" height="14" width="16" alt=""/></td></tr><tr><td class="button-BL-white"><img src="../Images/space.gif" height="8" width="17" alt=""/></td><td class="button-B-white"><img src="../Images/space.gif" height="8" width="4" alt=""/></td><td class="button-BR-white"><img src="../Images/space.gif" height="8" width="16" alt=""/></td></tr></table></td><td class="button_bar_cell"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button-TL-white"><img src="../Images/space.gif" height="5" width="17" alt=""/></td><td class="button-T-white"><img src="../Images/space.gif" height="5" width="4" alt=""/></td><td class="button-TR-white"><img src="../Images/space.gif" height="5" width="16" alt=""/></td></tr><tr><td class="button-L-white"><img src="../Images/space.gif" height="14" width="17" alt=""/></td><td class="button-white"><a id="CategoriesExportButton__Button" class="button_link" href="">Export</a></td><td class="button-R-white"><img src="../Images/space.gif" height="14" width="16" alt=""/></td></tr><tr><td class="button-BL-white"><img src="../Images/space.gif" height="8" width="17" alt=""/></td><td class="button-B-white"><img src="../Images/space.gif" height="8" width="4" alt=""/></td><td class="button-BR-white"><img src="../Images/space.gif" height="8" width="16" alt=""/></td></tr></table></td><td class="pagination_area"><table cellspacing="0" cellpadding="0" border="0"><tr><td><img src="../Images/space.gif" width="15" height="1" alt=""/></td><td class="pagination_label"><input type="image" name="CategoriesPagination$_FirstPage" id="CategoriesPagination__FirstPage" disabled="disabled" class="paginationButtonFirst" src="../Images/space.gif" style="border-width:0px;" /></td><td class="pagination_label"><input type="image" name="CategoriesPagination$_PreviousPage" id="CategoriesPagination__PreviousPage" disabled="disabled" class="paginationButtonPrevious" src="../Images/space.gif" style="border-width:0px;" /></td><td class="pagination_label" style="padding-right: 6px;">Page<b><span id="CategoriesPagination__CurrentPage">1</span></b>of<b><span id="CategoriesPagination__TotalPages">1</span></b></td><td class="pagination_label"><input type="image" name="CategoriesPagination$_NextPage" id="CategoriesPagination__NextPage" disabled="disabled" class="paginationButtonNext" src="../Images/space.gif" style="border-width:0px;" /></td><td class="pagination_label"><input type="image" name="CategoriesPagination$_LastPage" id="CategoriesPagination__LastPage" disabled="disabled" class="paginationButtonLast" src="../Images/space.gif" style="border-width:0px;" /></td><td class="pagination_label">Page Size <span onKeyPress="" ></span></td><td class="pagination_label"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button-TL-white"><img src="../Images/space.gif" height="5" width="17" alt=""/></td><td class="button-T-white"><img src="../Images/space.gif" height="5" width="4" alt=""/></td><td class="button-TR-white"><img src="../Images/space.gif" height="5" width="16" alt=""/></td></tr><tr><td class="button-L-white"><img src="../Images/space.gif" height="14" width="17" alt=""/></td><td class="button-white"><a id="CategoriesPagination__PageSizeButton__Button" class="button_link" href="">Go</a></td><td class="button-R-white"><img src="../Images/space.gif" height="14" width="16" alt=""/></td></tr><tr><td class="button-BL-white"><img src="../Images/space.gif" height="8" width="17" alt=""/></td><td class="button-B-white"><img src="../Images/space.gif" height="8" width="4" alt=""/></td><td class="button-BR-white"><img src="../Images/space.gif" height="8" width="16" alt=""/></td></tr></table></td><td class="pagination_label">Total Items:  <span id="CategoriesPagination__TotalItems">8</span></td></tr></table></td><td class="paginationRowEdgeR"><img src="../Images/space.gif" alt=""/></td></tr></table></td></tr><!--Table View Area --><tr><td class="tableRowsEdge"><table cellspacing="0" cellpadding="0" border="0" width="100%" onkeydown="captureUpDownKey(this, event)"><!-- This is the tables header row --><tr class="column_header"><th class="header_cell" colspan="3"><img src="../Images/space.gif" height="1" width="1" alt=""/></th><th class="header_cell" scope="col"><a id="CategoryNameLabel1" href="">Category Name</a></th><th class="header_cell" scope="col">Description</th></tr><!-- Table Rows --><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl00$CategoriesRecordRowEditButton" id="Row1_ctl00_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl00$CategoriesRecordRowViewButton" id="Row1_ctl00_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl00_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl00$CategoriesRecordRowSelection" /></td><td class="table_cell" >Beverages</td><td class="table_cell" >Soft drinks, coffees, teas, beers, and ales</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl01$CategoriesRecordRowEditButton" id="Row1_ctl01_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl01$CategoriesRecordRowViewButton" id="Row1_ctl01_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl01_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl01$CategoriesRecordRowSelection" /></td><td class="table_cell" >Condiments</td><td class="table_cell" >Sweet and savory sauces, relishes, spreads, and seasonings</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl02$CategoriesRecordRowEditButton" id="Row1_ctl02_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl02$CategoriesRecordRowViewButton" id="Row1_ctl02_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl02_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl02$CategoriesRecordRowSelection" /></td><td class="table_cell" >Confections</td><td class="table_cell" >Desserts, candies, and sweet breads</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl03$CategoriesRecordRowEditButton" id="Row1_ctl03_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl03$CategoriesRecordRowViewButton" id="Row1_ctl03_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl03_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl03$CategoriesRecordRowSelection" /></td><td class="table_cell" >Dairy Products</td><td class="table_cell" >Cheeses</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl04$CategoriesRecordRowEditButton" id="Row1_ctl04_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl04$CategoriesRecordRowViewButton" id="Row1_ctl04_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl04_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl04$CategoriesRecordRowSelection" /></td><td class="table_cell" >Grains/Cereals</td><td class="table_cell" >Breads, crackers, pasta, and cereal</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl05$CategoriesRecordRowEditButton" id="Row1_ctl05_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl05$CategoriesRecordRowViewButton" id="Row1_ctl05_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl05_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl05$CategoriesRecordRowSelection" /></td><td class="table_cell" >Meat/Poultry</td><td class="table_cell" >Prepared meats</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl06$CategoriesRecordRowEditButton" id="Row1_ctl06_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl06$CategoriesRecordRowViewButton" id="Row1_ctl06_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl06_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl06$CategoriesRecordRowSelection" /></td><td class="table_cell" >Produce</td><td class="table_cell" >Dried fruit and bean curd</td></tr><tr><td class="icon_cell" scope="row"><input type="image" name="Row1$ctl07$CategoriesRecordRowEditButton" id="Row1_ctl07_CategoriesRecordRowEditButton" class="button_link" RedirectURL="../Categories/EditCategoriesPage.aspx?Categories={PK}" src="../Images/icon_edit.gif" style="border-width:0px;" /></td><td class="icon_cell"><input type="image" name="Row1$ctl07$CategoriesRecordRowViewButton" id="Row1_ctl07_CategoriesRecordRowViewButton" class="button_link" RedirectURL="../Categories/ShowCategoriesPage.aspx?Categories={PK}" src="../Images/icon_view.gif" style="border-width:0px;" /></td><td class="icon_cell" onclick="moveToThisTableRow(this);"><input id="Row1_ctl07_CategoriesRecordRowSelection" type="checkbox" name="Row1$ctl07$CategoriesRecordRowSelection" /></td><td class="table_cell" >Seafood</td><td class="table_cell" >Seaweed and fish</td></tr><!-- Totals Area --></table></td></tr></table></td></tr></table></td></tr></table></td></tr></table></td></tr></table><!-- End Table Panel.html -->';
  2630.  
  2631.  
  2632. /**************************************************************************************
  2633.  *  Function    : getNextInnerHTML()                                                  *
  2634.  *  Description : Selects the next dummy "content" to be displayed in the popup.      *
  2635.  *                    (Just used for demo purposes; popup will use real data returned *
  2636.  *                    by AJAX call.)                                                  *
  2637.  *  Parameters  : None.                                                               *
  2638.  *  Returns     : Next dummy "content" to be displayed in the popup.                  *
  2639.  *  ISD Feature : "Detail Rollover Popup"                                             *
  2640.  *  Authors     : Samson Wong                                                         *
  2641.  **************************************************************************************/
  2642. function getNextInnerHTML() {
  2643.     
  2644.     var rInnerHTML = "";
  2645.     
  2646.     switch(gDisplayInnerHTML) {
  2647.         case 0:
  2648.             rInnerHTML = gInnerHTML0;
  2649.             break;
  2650.         case 1:
  2651.             rInnerHTML = gInnerHTML1;
  2652.             break;
  2653.         case 2:
  2654.             rInnerHTML = gInnerHTML2;
  2655.             break;
  2656.         case 3:
  2657.             rInnerHTML = gInnerHTML3;
  2658.             break;
  2659.     }
  2660.     
  2661.     gDisplayInnerHTML = (gDisplayInnerHTML + 1) % 4;
  2662.     
  2663.     return rInnerHTML;
  2664. }
  2665.  
  2666.  
  2667. /**************************************************************************************
  2668.  *  Function    : setRTL()                                                            *
  2669.  *  Description : Sets the boolean to indicate that the application is RTL.           *
  2670.  *  ISD Feature : "Detail Rollover Popup"                                             *
  2671.  *  Authors     : Samson Wong                                                         *
  2672.  **************************************************************************************/
  2673. function setRTL()
  2674. {
  2675.     gRTL = true; 
  2676. }
  2677.  
  2678.  
  2679. /**************************************************************************************
  2680.  *  Function    : clearRTL()                                                          *
  2681.  *  Description : Clears the boolean to indicate that the application is not RTL.     *
  2682.  *  ISD Feature : "Detail Rollover Popup"                                             *
  2683.  *  Authors     : Samson Wong                                                         *
  2684.  **************************************************************************************/
  2685. function clearRTL()
  2686. {
  2687.     gRTL = false; 
  2688. }
  2689.  
  2690.  
  2691. /**************************************************************************************
  2692.  *  Function    : delayRolloverPopup()                                                *
  2693.  *  Description : Starts a timer, and invokes the specified function upon timer       *
  2694.  *                    expiration.                                                     *
  2695.  *  Parameters  : aFunction, a piece of JavaScript code to execute.                   *
  2696.  *  ISD Feature : "Detail Rollover Popup"                                             *
  2697.  *  Authors     : Samson Wong                                                         *
  2698.  **************************************************************************************/
  2699. function delayRolloverPopup(aFunction, aDelay) {
  2700.     if (justDoIt == true) {
  2701.  
  2702.          // if valid piece of JavaScript passed in...
  2703.          if (aFunction != null)
  2704.          {
  2705.              if ((aDelay == null) || (aDelay <= 0))
  2706.              {
  2707.                  // set default delay to 500ms
  2708.                  aDelay = 500;
  2709.              }
  2710.              
  2711.             // clear any previous pending popup invocation
  2712.             if (gPopupTimer != null)
  2713.             {
  2714.                 clearTimeout(gPopupTimer);
  2715.                 gPopupTimer = null;
  2716.             }
  2717.             
  2718.             // reinvoke delayed popup
  2719.             gPopupTimer = setTimeout(aFunction, aDelay);
  2720.         }
  2721.     }
  2722. }
  2723.  
  2724. /**************************************************************************************
  2725.  *  Function    : detailRolloverPopup()                                              *
  2726.  *  Description : Displays "content" (returned from AJAX call) in a popup.            *
  2727.  *  Parameters  : aTitle, string to be displayed in title bar of popup                *
  2728.  *                aContent, string containing HTML to be displayed in body of popup.  *
  2729.  *                aPersist, boolean indicating whether popup should remain even on    *
  2730.  *                    mouseout.                                                       *
  2731.  *                aWidth, default width of AJAX popup                                 *
  2732.  *                aHeight, default height of AJAX popup                               *
  2733.  *                aIsScrollable, boolean indicating whether scroll bar should be      *
  2734.  *                    displayed if content is too long/wide for popup with specified  *
  2735.  *                    width and height                                                *
  2736.  *  ISD Feature : "Detail Rollover Popup"                                             *
  2737.  *  Authors     : Samson Wong                                                         *
  2738.  **************************************************************************************/
  2739. function detailRolloverPopup(aTitle, aContent, aPersist, aWidth, aHeight, aIsScrollable) {
  2740.     if (justDoIt == true) {
  2741.  
  2742.         // gRTL = true;
  2743.          // aTitle = gTitle;
  2744.         // aContent = gInnerHTML2;
  2745.         // aContent = '<img src="../Images/WhatISDDoesFlowchart.gif">';
  2746.         // aContent = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
  2747.         // aPersist = true;
  2748.         // aWidth = 400;
  2749.         // aHeight = 200;
  2750.         // aIsScrollable = false;
  2751.                 
  2752.         // if default size of popup is not specified...
  2753.         if ((aWidth == null) || (aHeight == null))
  2754.         {
  2755.             // set default size as 300x200px
  2756.             aWidth = 300;
  2757.             aHeight = 200;
  2758.         }
  2759.         // ...else if specified sizes are "too small/large"...
  2760.         else
  2761.         {
  2762.             // set a min/max size
  2763.             if (aWidth < 100)
  2764.             {
  2765.                 aWidth = 100;
  2766.             }
  2767.             else if (aWidth > 1000)
  2768.             {
  2769.                 aWidth = 1000;
  2770.             }
  2771.             
  2772.             if (aHeight < 100)
  2773.             {
  2774.                 aHeight = 100;
  2775.             }
  2776.             else if (aHeight > 1000)
  2777.             {
  2778.                 aHeight = 1000;
  2779.             }
  2780.         }
  2781.         
  2782.         if (aIsScrollable)
  2783.         {
  2784.             // define scrollable region
  2785.               aContent = '<div style="clear:both;height:' + aHeight + 'px;width:' + aWidth + 'px;overflow:auto;">' + aContent + '</div>';
  2786.         }
  2787.  
  2788.         var lPageOffsetX;
  2789.         var lPageOffsetY;
  2790.         var lClientHeight;
  2791.         var lClientWidth;
  2792.         
  2793.         // determine browser window scrolled position
  2794.         lPageOffsetX = document.documentElement.scrollLeft;
  2795.         lPageOffsetY = document.documentElement.scrollTop;
  2796.         
  2797.         // determine current browser window dimensions in IE
  2798.         if (document.all)
  2799.         {
  2800.             lClientHeight = document.documentElement.clientHeight;
  2801.             lClientWidth = document.documentElement.clientWidth;
  2802.         }
  2803.         else // in Firefox
  2804.         {
  2805.             lClientHeight = window.innerHeight;
  2806.             lClientWidth = window.innerWidth;
  2807.         }
  2808.         
  2809.         // determine mouse cursor position (top left, top right, bottom left, or bottom right) relative to current browser window
  2810.         var lRelativeX = gEventClientX - lPageOffsetX;
  2811.          var lRelativeY = gEventClientY - lPageOffsetY;
  2812.            var lInLeftHalf;
  2813.            var lInTopHalf;
  2814.   
  2815.         if (lRelativeX <= (lClientWidth/2))
  2816.         {
  2817.             if (!gRTL)
  2818.             {
  2819.                 lInLeftHalf = true;
  2820.             }
  2821.             else
  2822.             {
  2823.                 lInLeftHalf = false;
  2824.             }
  2825.         }
  2826.         else
  2827.         {
  2828.              if (!gRTL)
  2829.             {
  2830.                    lInLeftHalf = false;
  2831.                }
  2832.                else
  2833.                {
  2834.                    lInLeftHalf = true;
  2835.                }
  2836.         }
  2837.         
  2838.         if (lRelativeY <= (lClientHeight/2))
  2839.         {
  2840.             lInTopHalf = true;
  2841.         }
  2842.         else
  2843.         {
  2844.             lInTopHalf = false;
  2845.         }
  2846.         
  2847.         // determine PNG support based on broswer version (for IE6 or lower, we'll need to use css filters to simulate PNG transparency)
  2848.         var lPNGSupported = true;
  2849.         
  2850.         /* remove support for non-PNG-supporting IE6 (this will resolve the non-compliant "filter" css errors)
  2851.         if (navigator.appName == "Microsoft Internet Explorer")
  2852.         {
  2853.             var lIEVersion = 0;
  2854.             if (navigator.appVersion.indexOf("MSIE") != -1)
  2855.             {
  2856.                 var lIEAppVersionStringArray = navigator.appVersion.split("MSIE");
  2857.                 lIEVersion = parseFloat(lIEAppVersionStringArray[1]);
  2858.             }
  2859.  
  2860.             if (lIEVersion < 7)
  2861.             {
  2862.                 lPNGSupported = false;
  2863.             }
  2864.         }
  2865.         */
  2866.  
  2867.         // correct for IE RTL offset
  2868.         if ((document.all) && (gRTL))
  2869.         {
  2870.             gEventClientX -= (document.documentElement.scrollWidth - lClientWidth + 20);
  2871.         }
  2872.                  
  2873.         // create appropriate html shell to display popup in correct location relative to mouse cursor position
  2874.         var lInnerHTML;
  2875.         if (lInLeftHalf && lInTopHalf)
  2876.         {
  2877.             // alert("detailRolloverPopup(inNW)");
  2878.             gEventClientX = gEventClientX + 10;
  2879.             if (gRTL)
  2880.             {
  2881.                 gEventClientX -= 450;
  2882.             }
  2883.             gEventClientY = gEventClientY - 60;
  2884.             /*
  2885.             if (lPNGSupported)
  2886.             {
  2887.             */
  2888.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL"> </td><td class="detailRolloverT" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  2889.                                     + aTitle
  2890.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR"> </td></tr><td class="detailRolloverL"><img src="../Images/';
  2891.                                     
  2892.                 if (!gRTL)
  2893.                 {
  2894.                     lInnerHTML += 'detailRolloverPoint.png';
  2895.                 }
  2896.                 else
  2897.                 {
  2898.                     lInnerHTML += 'detailRolloverPoint.rtl.png';
  2899.                 }
  2900.                 
  2901.                 lInnerHTML += '"></td><td class="detailRolloverC" style="padding:2px;">'
  2902.                                     + aContent
  2903.                                     + '</td><td class="detailRolloverR">            </td></tr><tr><td class="detailRolloverBL"> </td><td class="detailRolloverB"> </td><td class="detailRolloverBR"> </td></tr></table>';
  2904.            /*
  2905.             }
  2906.             else
  2907.             {
  2908.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL_noPNG"> </td><td class="detailRolloverT_noPNG" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  2909.                                     + aTitle
  2910.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR_noPNG"> </td></tr><td class="detailRolloverL_noPNG"><div style="width:65px;height:84px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=image, src=\'../Images/';
  2911.                                     
  2912.                 if (!gRTL)
  2913.                 {
  2914.                     lInnerHTML += 'detailRolloverPoint.png';
  2915.                 }
  2916.                 else
  2917.                 {
  2918.                     lInnerHTML += 'detailRolloverPoint.rtl.png';
  2919.                 }
  2920.                 
  2921.                 lInnerHTML += '\');"></div></td><td class="detailRolloverC" style="padding:2px;">'
  2922.                                     + aContent
  2923.                                     + '</td><td class="detailRolloverR_noPNG">            </td></tr><tr><td class="detailRolloverBL_noPNG"> </td><td class="detailRolloverB_noPNG"> </td><td class="detailRolloverBR_noPNG"> </td></tr></table>';
  2924.             }
  2925.             */
  2926.         }
  2927.          else if (!lInLeftHalf && lInTopHalf)
  2928.         {
  2929.             // alert("detailRolloverPopup(inNE)");
  2930.             gEventClientX = gEventClientX - (140 + aWidth);
  2931.             if (gRTL)
  2932.             {
  2933.                 gEventClientX += 450;            
  2934.             }
  2935.             gEventClientY = gEventClientY - 60;
  2936.             /*
  2937.             if (lPNGSupported)
  2938.             {
  2939.             */
  2940.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL"> </td><td class="detailRolloverT" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  2941.                                     + aTitle
  2942.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR"> </td></tr><td class="detailRolloverL">            </td><td class="detailRolloverC" style="padding:2px;">'
  2943.                                     + aContent
  2944.                                     + '</td><td class="detailRolloverR"><img src="../Images/';
  2945.                                     
  2946.                 if (!gRTL)
  2947.                 {
  2948.                     lInnerHTML += 'detailRolloverPoint.rtl.png';
  2949.                 }
  2950.                 else
  2951.                 {
  2952.                     lInnerHTML += 'detailRolloverPoint.png';
  2953.                 }
  2954.                                     
  2955.                 lInnerHTML += '"></td></tr><tr><td class="detailRolloverBL"> </td><td class="detailRolloverB"> </td><td class="detailRolloverBR"> </td></tr></table>';
  2956.             /*
  2957.             }
  2958.             else
  2959.             {
  2960.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL_noPNG"> </td><td class="detailRolloverT_noPNG" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  2961.                                     + aTitle
  2962.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR_noPNG"> </td></tr><td class="detailRolloverL_noPNG">            </td><td class="detailRolloverC" style="padding:2px;">'
  2963.                                     + aContent
  2964.                                     + '</td><td class="detailRolloverR_noPNG"><div style="width:65px;height:84px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=image, src=\'../Images/';
  2965.                                     
  2966.                 if (!gRTL)
  2967.                 {
  2968.                     lInnerHTML += 'detailRolloverPoint.rtl.png';
  2969.                 }
  2970.                 else
  2971.                 {
  2972.                     lInnerHTML += 'detailRolloverPoint.png';
  2973.                 }
  2974.                                     
  2975.                 lInnerHTML += '\');"></div></td></tr><tr><td class="detailRolloverBL_noPNG"> </td><td class="detailRolloverB_noPNG"> </td><td class="detailRolloverBR_noPNG"> </td></tr></table>';        
  2976.             }
  2977.             */
  2978.         }
  2979.         else if (lInLeftHalf && !lInTopHalf)
  2980.         {
  2981.             // alert("detailRolloverPopup(inSW)");
  2982.             gEventClientX = gEventClientX + 6;
  2983.             if (gRTL)
  2984.             {
  2985.                 gEventClientX -= 450;
  2986.             }            
  2987.             gEventClientY = gEventClientY - (45 + aHeight);
  2988.             /*
  2989.             if (lPNGSupported)
  2990.             {
  2991.             */
  2992.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL"> </td><td class="detailRolloverT" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  2993.                                     + aTitle
  2994.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR"> </td></tr><td class="detailRolloverL" style="padding-bottom:15px;vertical-align:bottom;"><img src="../Images/';
  2995.                                     
  2996.                 if (!gRTL)
  2997.                 {
  2998.                     lInnerHTML += 'detailRolloverPoint.btt.png';
  2999.                 }
  3000.                 else
  3001.                 {
  3002.                     lInnerHTML += 'detailRolloverPoint.btt.rtl.png';
  3003.                 }
  3004.                                     
  3005.                 lInnerHTML += '"></td><td class="detailRolloverC" style="padding:2px;">'
  3006.                                     + aContent
  3007.                                     + '</td><td class="detailRolloverR">            </td></tr><tr><td class="detailRolloverBL"> </td><td class="detailRolloverB"> </td><td class="detailRolloverBR"> </td></tr></table>';
  3008.            /*
  3009.             }
  3010.             else
  3011.             {
  3012.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL_noPNG"> </td><td class="detailRolloverT_noPNG" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  3013.                                     + aTitle
  3014.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR_noPNG"> </td></tr><td class="detailRolloverL_noPNG" style="padding-bottom:15px;vertical-align:bottom;"><div style="width:65px;height:84px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=image, src=\'../Images/';
  3015.                                     
  3016.                 if (!gRTL)
  3017.                 {
  3018.                     lInnerHTML += 'detailRolloverPoint.btt.png';
  3019.                 }
  3020.                 else
  3021.                 {
  3022.                     lInnerHTML += 'detailRolloverPoint.btt.rtl.png';
  3023.                 }
  3024.                                     
  3025.                 lInnerHTML += '\');"></div></td><td class="detailRolloverC" style="padding:2px;">'
  3026.                                     + aContent
  3027.                                     + '</td><td class="detailRolloverR_noPNG">            </td></tr><tr><td class="detailRolloverBL_noPNG"> </td><td class="detailRolloverB_noPNG"> </td><td class="detailRolloverBR_noPNG"> </td></tr></table>';            
  3028.             }      
  3029.             */                              
  3030.         }
  3031.         else // (!lInLeftHalf && !InTopHalf)
  3032.         {
  3033.             // alert("detailRolloverPopup(inSE)");
  3034.             gEventClientX = gEventClientX - (140 + aWidth);
  3035.             if (gRTL)
  3036.             {
  3037.                 gEventClientX += 450;
  3038.             }            
  3039.             gEventClientY = gEventClientY - (45 + aHeight);
  3040.             /*
  3041.             if (lPNGSupported)
  3042.             {
  3043.             */
  3044.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL"> </td><td class="detailRolloverT" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  3045.                                     + aTitle
  3046.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR"> </td></tr><td class="detailRolloverL">            </td><td class="detailRolloverC" style="padding:2px;">'
  3047.                                     + aContent
  3048.                                     + '</td><td class="detailRolloverR" style="padding-bottom:15px;vertical-align:bottom;"><img src="../Images/';
  3049.                                     
  3050.                 if (!gRTL)
  3051.                 {
  3052.                     lInnerHTML += 'detailRolloverPoint.btt.rtl.png';
  3053.                 }
  3054.                 else
  3055.                 {
  3056.                     lInnerHTML += 'detailRolloverPoint.btt.png';
  3057.                 }
  3058.                                     
  3059.                 lInnerHTML += '"></div></td></tr><tr><td class="detailRolloverBL"> </td><td class="detailRolloverB"> </td><td class="detailRolloverBR"> </td></tr></table>';
  3060.             /*
  3061.             }
  3062.             else
  3063.             {
  3064.                 lInnerHTML = '<table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTL_noPNG"> </td><td class="detailRolloverT_noPNG" style="vertical-align:middle;"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="detailRolloverTitle"><br><br>'
  3065.                                     + aTitle
  3066.                                     + '</td><td class="detailRolloverPopupCloseButtonAlignment"><a onclick="gPersist=false;detailRolloverPopupClose();"><img id="detailRolloverPopupCloseButton" src="../Images/closeButton.gif" border="0"></a></td></tr></table></td><td class="detailRolloverTR_noPNG"> </td></tr><td class="detailRolloverL_noPNG">            </td><td class="detailRolloverC" style="padding:2px;">'
  3067.                                     + aContent
  3068.                                     + '</td><td class="detailRolloverR_noPNG" style="padding-bottom:15px;vertical-align:bottom;"><div style="width:65px;height:84px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=image, src=\'../Images/';
  3069.                                     
  3070.                 if (!gRTL)
  3071.                 {
  3072.                     lInnerHTML += 'detailRolloverPoint.btt.rtl.png';
  3073.                 }
  3074.                 else
  3075.                 {
  3076.                     lInnerHTML += 'detailRolloverPoint.btt.png';
  3077.                 }
  3078.                                     
  3079.                    lInnerHTML += '\');"></div></td></tr><tr><td class="detailRolloverBL_noPNG"> </td><td class="detailRolloverB_noPNG"> </td><td class="detailRolloverBR_noPNG"> </td></tr></table>';    
  3080.             }
  3081.             */
  3082.         }
  3083.           
  3084.         gPersist = aPersist;
  3085.         var popupNode = document.getElementById("detailPopup");
  3086.         popupNode.innerHTML = lInnerHTML;
  3087.         popupNode.style.top = (gEventClientY) + "px";
  3088.         popupNode.style.left = (gEventClientX) + "px";
  3089.     }
  3090. }
  3091.  
  3092.  
  3093. /**************************************************************************************
  3094.  *  Function    : detailRolloverPopupClose()                                          *
  3095.  *  Description : Closes (previously invoked by onmouseover/onclick event) popup.     *
  3096.  *  Parameters  : None.                                                               *
  3097.  *  ISD Feature : "Detail Rollover Popup"                                             *
  3098.  *  Authors     : Samson Wong                                                         *
  3099.  **************************************************************************************/
  3100. function detailRolloverPopupClose() {
  3101.  
  3102.     if (justDoIt == true) {
  3103.     
  3104.         // clear any previous pending popup invocation
  3105.         if (gPopupTimer != null)
  3106.         {
  3107.             clearTimeout(gPopupTimer);
  3108.             gPopupTimer = null;
  3109.         }
  3110.             
  3111.         if (gPersist != true) {
  3112.             // document.getElementById("detailPopup").innerHTML = "";
  3113.             gPopupTimer = setTimeout('document.getElementById("detailPopup").innerHTML = "";', 250);            
  3114.         }
  3115.     }
  3116. }
  3117.  
  3118. /**************************************************************************************
  3119.  *  Function    : SaveMousePosition()                                                 *
  3120.  *  Description : Saves the mouse position for use by detailRolloverPopup         *
  3121.  *  Parameters  : event, reference to mouseover/onclick event                 *
  3122.  **************************************************************************************/
  3123.  
  3124. var gEventClientX = 0;
  3125. var gEventClientY = 0;
  3126.  
  3127. // save latest coordinates (based on last mouse movement) instead of using those saved
  3128. // an AJAX-popup-delay (default 500ms) earlier
  3129. var IE = document.all?true:false;
  3130. if (!IE) document.captureEvents(Event.MOUSEMOVE)
  3131. document.onmousemove = SaveMousePosition;
  3132.  
  3133. function SaveMousePosition(evt)
  3134. {
  3135.     gEventClientX = mouseX(evt);
  3136.     gEventClientY = mouseY(evt);
  3137. }
  3138.  
  3139. function mouseX(evt) {
  3140.     evt = evt || window.event;
  3141.     if (evt.pageX) return evt.pageX;
  3142.     else if (evt.clientX)
  3143.         return evt.clientX + (document.documentElement.scrollLeft ?
  3144.             document.documentElement.scrollLeft :
  3145.             document.body.scrollLeft);
  3146.     else return null;
  3147. }
  3148.  
  3149.  
  3150. function mouseY(evt) {
  3151.     evt = evt || window.event;
  3152.     if (evt.pageY) return evt.pageY;
  3153.     else if (evt.clientY)
  3154.         return evt.clientY + (document.documentElement.scrollTop ?
  3155.             document.documentElement.scrollTop :
  3156.             document.body.scrollTop);
  3157.     else return null;
  3158. }
  3159.  
  3160.  
  3161. /**************************************************************************************
  3162.  *  Description : Global variables used by "Date Formatter" feature.                  *
  3163.  *  ISD Feature : "Date Formatter"                                                    *
  3164.  *  Author      : Samson Wong                                                         *
  3165.  **************************************************************************************/
  3166. var gDateSeparator1 = "/";      // single character separator of first two components of date string ("m"s, "d"s, and "y"s)
  3167. var gDateSeparator2 = "/";      // single character separator of last two components of date string ("m"s, "d"s, and "y"s)
  3168. var gPreviousDatePattern = ""; // last recorded date pattern
  3169. var gDatePatternArray= null;   // split portions of date pattern
  3170. var gDateMonthPosition = 1;    // position of month portion within date pattern
  3171. var gDateDayPosition = 2;      // position of day portion within date pattern
  3172. var gDateYearPosition = 3;     // position of year portion within date pattern
  3173. var gDateFormatterState = "0"  // current date formatter state machine state
  3174. var gDateStringEntered = "";   // last value in date textbox
  3175. var gCurrentValidDateArray = new Array(3);
  3176.  
  3177.  
  3178. // Check browser version
  3179. var isNav4 = false, isNav5 = false, isIE4 = false
  3180.  
  3181. if(navigator.appName == "Netscape") 
  3182. {
  3183.    if (navigator.appVersion < "5")  
  3184.    {
  3185.       isNav4 = true;
  3186.       isNav5 = false;
  3187.     }
  3188.    else
  3189.    if (navigator.appVersion > "4") 
  3190.    {
  3191.       isNav4 = false;
  3192.       isNav5 = true;
  3193.     }
  3194. }
  3195. else  
  3196. {
  3197.    isIE4 = true;
  3198. }
  3199.  
  3200.  
  3201. /**************************************************************************************
  3202.  *  Function    : initializeDateFormatter()                                           *
  3203.  *  Author      : Samson Wong                                                         *
  3204.  **************************************************************************************/
  3205. function initializeDateFormatter(aInputTextbox) {
  3206.     gDateSeparator1 = "/";
  3207.     gDateSeparator2 = "/";
  3208.     gPreviousDatePattern = "";
  3209.     gDatePatternArray = null;
  3210.     gDateMonthPosition = 1;
  3211.     gDateDayPosition = 2;
  3212.     gDateYearPosition = 3;
  3213.     gDateFormatterState = "0";
  3214.     gCurrentValidDateString = new Array(3);
  3215.     gDateStringEntered = "";
  3216. }
  3217.  
  3218. function myAlert(aAlertString) {
  3219.     var debug = false;
  3220.     if (debug) {
  3221.         alert(aAlertString);
  3222.     }
  3223. }
  3224.  
  3225. /**************************************************************************************
  3226.  *  Function    : toggleEnableDisableDateFormatter()                                  *
  3227.  *  Description : Enables/disables Date Formatter.  On onfocus change (tabbing or     *
  3228.  *                    onclick), pasting, backspacing/deleting, or left/right          *
  3229.  *                    arrowing, date formatter is enabled if the date textbox is      *
  3230.  *                    empty; disabled, otherwise (in which case the user is allowed   *
  3231.  *                    to enter whatever he/she wishes, and date validation is only    *
  3232.  *                    performed upon onblur).                                         *
  3233.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3234.  *                    enters the date string                                          *
  3235.  *                aDatePattern, date pattern (containing some combination of "m"s,    *
  3236.  *                    "s"s, "y"s, and "separators" to which the user-inputted date    *
  3237.  *                     string is to be formated                                       *
  3238.  *  ISD Feature : "Date Formatter"                                                    *
  3239.  *  Author      : Samson Wong                                                         *
  3240.  **************************************************************************************/
  3241. function toggleEnableDisableDateFormatter(aInputTextbox, aDatePattern)  {
  3242.  
  3243.     aInputTextbox.style.background = "#ffffff";
  3244.     initializeDateFormatter(aInputTextbox);
  3245.  
  3246.     // myAlert("onfocus:gPreviousDatePattern(" + gPreviousDatePattern + "), aDatePattern(" + aDatePattern + ")");
  3247.     // re-parse date pattern only if different from that in previous call
  3248.     if (gPreviousDatePattern != aDatePattern) { 
  3249.         // parse date pattern
  3250.         if (!parseDatePattern(aInputTextbox, aDatePattern)) {
  3251.             goToNextState("DisableDateFormatter");
  3252.             return false;
  3253.         }       
  3254.     }
  3255.  
  3256.     if (aInputTextbox.value != "") {
  3257.         // myAlert("toggleEnableDisableDateFormatter(disabling:" + aInputTextbox.value + ")");
  3258.         goToNextState("DisableDateFormatter");
  3259.     }
  3260.     // else {
  3261.         // myAlert("toggleEnableDisableDateFormatter(enabling:" + aInputTextbox.value + ")");
  3262.     // }
  3263. }
  3264.  
  3265.  
  3266. /**************************************************************************************
  3267.  *  Function    : DateFormat()                                                        *
  3268.  *  Description : This event handler accepts user-inputted date string, and           *
  3269.  *                    auto-formats it according to the required date pattern.         *
  3270.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3271.  *                    enters the date string                                          *
  3272.  *                aDateStringEntered, current contents (value) in the input textbox   * 
  3273.  *                aEvent, reference to event (onkeyup) causing this event handler to  *
  3274.  *                    be called                                                       *
  3275.  *                aDatePattern, date pattern (containing some combination of "m"s,    *
  3276.  *                    "s"s, "y"s, and "separators" to which the user-inputted date    *
  3277.  *                     string is to be formated                                       *
  3278.  *  Returns:    : false, if an invalid date digit is entered (it is automatically     *
  3279.  *                    cleared for the user)                                           *
  3280.  *                true, if valid date digit is entered                                *
  3281.  *  ISD Feature : "Date Formatter"                                                    *
  3282.  *  Author      : Samson Wong                                                         *
  3283.  **************************************************************************************/
  3284. function DateFormat(aInputTextbox, aDateStringEntered, aEvent, aDatePattern)  {
  3285.  
  3286.     // if (justDoIt == true) {
  3287.     
  3288.         var whichCode;
  3289.         if (typeof(aEvent) == "number") {
  3290.             whichCode = aEvent;
  3291.         }
  3292.         else {
  3293.             whichCode = (window.Event) ? aEvent.which : aEvent.keyCode;
  3294.         }
  3295.         
  3296.         // if backspace, delete, left arrow, or right arrow...
  3297.         /*
  3298.         if ( (whichCode == 8) || (whichCode == 46) || (whichCode == 37) || (whichCode == 39) ) {
  3299.  
  3300.             if (!toggleEnableDisableDateFormatter(aInputTextbox, aDatePattern)) {
  3301.                 return false;
  3302.             }
  3303.         }
  3304.         */
  3305.         // if Ctrl-v...
  3306.         /*
  3307.         else if (whichCode == 86) {
  3308.             // allow "pasting" of "copied" text into date field, but disable date formatter because
  3309.             //    user could have pasted anything (date validation will still be performed onblur)
  3310.             goToNextState("DisableDateFormatter");
  3311.         }
  3312.         */
  3313.         // if "up arrow" or "plus"
  3314.         if ((whichCode == 38) || (whichCode == 107)) {
  3315.             if ((gDatePatternArray == null) || (gPreviousDatePattern == "") || (gPreviousDatePattern != aDatePattern))
  3316.             {
  3317.                 toggleEnableDisableDateFormatter(aInputTextbox, aDatePattern);
  3318.             }
  3319.  
  3320.             while ((whichCode == 107) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "+"))
  3321.             {
  3322.                 aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1);
  3323.             }
  3324.             
  3325.             // if date field not initialized...
  3326.             if (aInputTextbox.value == "") {
  3327.                 // display today's date
  3328.                 var lCurrentDate = new Date();
  3329.                 displayDate(aInputTextbox, lCurrentDate);
  3330.             }
  3331.             else {                    
  3332.                 if (presubmitDateValidation(aInputTextbox, aDatePattern)) {
  3333.                     // create new date object based on current contents of date field
  3334.                     var lCurrentDate = createNewDate(aInputTextbox);
  3335.                     
  3336.                     // if not a credit card expiration date (which lacks a day field)...
  3337.                     if (gDateDayPosition != 0)
  3338.                     {
  3339.                         // increment to next day (1000ms/s * 60s/min + 60min/hr + 24hr/day = 86400000ms/day)
  3340.                         lCurrentDate.setTime(lCurrentDate.getTime() + 86400000);
  3341.                     }
  3342.                     else
  3343.                     {
  3344.                         if (lCurrentDate.getMonth() != 11)
  3345.                         {
  3346.                             lCurrentDate.setMonth(lCurrentDate.getMonth()+1);
  3347.                         }
  3348.                         else
  3349.                         {
  3350.                             if (new Number(lCurrentDate.getYear()) < 9999)
  3351.                             {
  3352.                                 lCurrentDate.setMonth(0);
  3353.                                 lCurrentDate.setYear(lCurrentDate.getYear()+1);
  3354.                             }
  3355.                         }
  3356.                     }
  3357.                     
  3358.                     // display new date
  3359.                     displayDate(aInputTextbox, lCurrentDate);
  3360.                 }
  3361.             }
  3362.         }
  3363.         // if "down arrow" or "minus"
  3364.         else if ((whichCode == 40) || (whichCode == 109)) {
  3365.             if ((gDatePatternArray == null) || (gPreviousDatePattern == "") || (gPreviousDatePattern != aDatePattern))
  3366.             {
  3367.                 toggleEnableDisableDateFormatter(aInputTextbox, aDatePattern);
  3368.             }
  3369.  
  3370.             while ((whichCode == 109) && (aInputTextbox.value.charAt(aInputTextbox.value.length-1) == "-"))
  3371.              {
  3372.                 aInputTextbox.value = (aInputTextbox.value).substring(0,aInputTextbox.value.length-1);
  3373.             }
  3374.  
  3375.             // if date field not initialized...
  3376.             if (aInputTextbox.value == "") {
  3377.                 // display today's date
  3378.                 var lCurrentDate = new Date();
  3379.                 displayDate(aInputTextbox, lCurrentDate);
  3380.             }
  3381.             else {                    
  3382.                 if (presubmitDateValidation(aInputTextbox, aDatePattern)) {
  3383.                 
  3384.                     // create new date object based on current contents of date field
  3385.                     var lCurrentDate = createNewDate(aInputTextbox);
  3386.  
  3387.                     // if not a credit card expiration date (which lacks a day field)...
  3388.                     if (gDateDayPosition != 0)
  3389.                     {                    
  3390.                         // decrement to previous day (1000ms/s * 60s/min + 60min/hr + 24hr/day = 86400000ms/day)
  3391.                         lCurrentDate.setTime(lCurrentDate.getTime() - 86400000);
  3392.                     }
  3393.                     else
  3394.                     {
  3395.                         if (lCurrentDate.getMonth() != 0)
  3396.                         {
  3397.                             lCurrentDate.setMonth(lCurrentDate.getMonth()-1);
  3398.                         }
  3399.                         else
  3400.                         {
  3401.                             if (new Number(lCurrentDate.getYear()) > 1000)
  3402.                             {
  3403.                                 lCurrentDate.setMonth(11);
  3404.                                 lCurrentDate.setYear(lCurrentDate.getYear()-1);
  3405.                             }
  3406.                         }
  3407.                     }
  3408.                     
  3409.                     // display new date
  3410.                     displayDate(aInputTextbox, lCurrentDate);
  3411.                 }
  3412.             }
  3413.         }  
  3414.         /*  
  3415.         else
  3416.         {
  3417.             // if date formatter not disabled...
  3418.             if ((gDateFormatterState != "4") || (aInputTextbox.value.length == 1)) {
  3419.             
  3420.                 // re-parse date pattern only if different from that in previous call
  3421.                 if (gPreviousDatePattern != aDatePattern) { 
  3422.                     // parse date pattern
  3423.                     if (!parseDatePattern(aInputTextbox, aDatePattern)) {
  3424.                         goToNextState("DisableDateFormatter");
  3425.                         return false;
  3426.                     }       
  3427.                 }
  3428.                 
  3429.                 // convert numpad digit entries into regular (top of) keyboard digits
  3430.                 if ((whichCode >=96) && (whichCode <=105)) {
  3431.                     whichCode -= 48;
  3432.                 }
  3433.                 else if ((whichCode == 111) || (whichCode == 191)) {
  3434.                     // date separator "/" returns whichCode 111 (from numpad) and 191 (from keyboard), but should be 47
  3435.                     whichCode = 47;
  3436.                 }
  3437.                 
  3438.                 aInputTextbox.value = gDateStringEntered + String.fromCharCode(whichCode);
  3439.         
  3440.                 var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  3441.                 // myAlert("DateFormat(lLastCharEntered=" + lLastCharEntered + ",whichCode=" + whichCode + ")");
  3442.             
  3443.                 var lValidDigits = "1234567890";    
  3444.                 // if last character entered is not a numerical digit nor the date separator...
  3445.                 if ((lValidDigits.indexOf(lLastCharEntered) == -1) && (lLastCharEntered != gDateSeparator1) && (lLastCharEntered != gDateSeparator2)) {
  3446.                 // sam (original) - not needed
  3447.                 // sam - fixed bug in original code where once one invalid character is accepted (because of "quick typing" race condition)
  3448.                 //     all further alphabetic checking fails (i.e., all subsequent invalid characters are accepted)
  3449.                 //if (alphaCheck.indexOf(gDateStringEntered.charAt(gDateStringEntered.length-1)) >= 1)  
  3450.                 //{
  3451.                     clearLastCharEntered(aInputTextbox);
  3452.         
  3453.                     return false;
  3454.                 }
  3455.                 
  3456.                 if (gPreviousDatePattern != "") {
  3457.                 
  3458.                     // enter state machine
  3459.                     switch(gDateFormatterState) {
  3460.                         case "0": // empty date string
  3461.                             if (gDateMonthPosition == 1) {
  3462.                                 processFirstMonthDigit(aInputTextbox, gDateStringEntered);
  3463.                             }
  3464.                             else if (gDateDayPosition == 1) {
  3465.                                 processFirstDayDigit(aInputTextbox, gDateStringEntered);
  3466.                             }
  3467.                             // year portion of date pattern is in first position
  3468.                             else {
  3469.                                 processFirstYearDigit(aInputTextbox, gDateStringEntered);
  3470.                             }
  3471.                             break;
  3472.                         case "0.1": // validating first portion of date string, and at least one digit has already been entered for it
  3473.                             if (gDateMonthPosition == 1) {
  3474.                                 processSecondMonthDigit(aInputTextbox, gDateStringEntered);
  3475.                             }
  3476.                             else if (gDateDayPosition == 1) {
  3477.                                 processSecondDayDigit(aInputTextbox, gDateStringEntered);
  3478.                             }
  3479.                             // year portion of date pattern is in first position
  3480.                             else {
  3481.                                 processSucceedingYearDigit(aInputTextbox, gDateStringEntered);
  3482.                             }               
  3483.                             break;
  3484.                         case "1": // first portion of date string validated, awaiting first digit of second portion
  3485.                             if (gDateMonthPosition == 2) {
  3486.                                 processFirstMonthDigit(aInputTextbox, gDateStringEntered);
  3487.                             }
  3488.                             else if (gDateDayPosition == 2) {
  3489.                                 processFirstDayDigit(aInputTextbox, gDateStringEntered);
  3490.                             }
  3491.                             // year portion of date pattern is in second position
  3492.                             else {
  3493.                                 processFirstYearDigit(aInputTextbox, gDateStringEntered);
  3494.                             }               
  3495.                             break;
  3496.                         case "1.1": // validating second portion of date sring, and at least one digit has already been entered for it
  3497.                             if (gDateMonthPosition == 2) {
  3498.                                 processSecondMonthDigit(aInputTextbox, gDateStringEntered);
  3499.                             }
  3500.                             else if (gDateDayPosition == 2) {
  3501.                                 processSecondDayDigit(aInputTextbox, gDateStringEntered);
  3502.                             }
  3503.                             // year portion of date pattern is in second position
  3504.                             else {
  3505.                                 processSucceedingYearDigit(aInputTextbox, gDateStringEntered);
  3506.                             }               
  3507.                             break;
  3508.                         case "2":
  3509.                             if (gDateMonthPosition == 3) {
  3510.                                 processFirstMonthDigit(aInputTextbox, gDateStringEntered);
  3511.                             }
  3512.                             else if (gDateDayPosition == 3) {
  3513.                                 processFirstDayDigit(aInputTextbox, gDateStringEntered);
  3514.                             }
  3515.                             // year portion of date pattern is in third position
  3516.                             else if (gDateYearPosition == 3) {
  3517.                                 processFirstYearDigit(aInputTextbox, gDateStringEntered);
  3518.                             }   
  3519.                             // no third date portion (e.g., credit card expiration date mm/yyyy)
  3520.                             else {
  3521.                                 // clear last digit entered; disallow all addition digit entry (await onblur date validation)
  3522.                                 aInputTextbox.value = aInputTextbox.value.substring(0, gDateStringEntered.length-1);
  3523.                                 gDateFormatterState = "3";
  3524.                             }           
  3525.                             break;
  3526.                         case "2.1":
  3527.                             if (gDateMonthPosition == 3) {
  3528.                                 processSecondMonthDigit(aInputTextbox, gDateStringEntered);
  3529.                             }
  3530.                             else if (gDateDayPosition == 3) {
  3531.                                 processSecondDayDigit(aInputTextbox, gDateStringEntered);
  3532.                             }
  3533.                             // year portion of date pattern is in third position
  3534.                             else {
  3535.                                 processSucceedingYearDigit(aInputTextbox, gDateStringEntered);
  3536.                             }               
  3537.                             break;
  3538.                         case "3":
  3539.                             // disallow all addition digit entry (await onblur date validation)
  3540.                             aInputTextbox.value = aInputTextbox.value.substring(0, gDateStringEntered.length);
  3541.                             break;
  3542.                     }
  3543.                 }
  3544.             }
  3545.         }
  3546.         */
  3547.         
  3548.         // save current valid string entered
  3549.         gDateStringEntered = aInputTextbox.value;
  3550.  
  3551.         return true;
  3552.     // }
  3553. }
  3554.  
  3555.  
  3556. /**************************************************************************************
  3557.  *  Function    : goToNextState()                                                     *
  3558.  *  Description : Updates the state machine to the next state following               *
  3559.  *                    "portionUpdated".                                               *
  3560.  *  Parameters  : portionUpdated, last state of parser                                *
  3561.  *  Returns:    : None.                                                               *
  3562.  *  ISD Feature : "Date Formatter"                                                    *
  3563.  *  Author      : Samson Wong                                                         *
  3564.  **************************************************************************************/
  3565. function goToNextState(portionUpdated) {
  3566.     switch(portionUpdated) {
  3567.         case "FirstMonthDigit":
  3568.             switch(gDateMonthPosition) {
  3569.                 case 1:
  3570.                     gDateFormatterState = "0.1";
  3571.                     break;
  3572.                 case 2:
  3573.                     gDateFormatterState = "1.1";
  3574.                     break;
  3575.                 case 3:
  3576.                     gDateFormatterState = "2.1";
  3577.                     break;
  3578.             }
  3579.             break;
  3580.         case "SecondMonthDigit":
  3581.             switch(gDateMonthPosition) {
  3582.                 case 1:
  3583.                     gDateFormatterState = "1";
  3584.                     break;
  3585.                 case 2:
  3586.                     gDateFormatterState = "2";
  3587.                     break;
  3588.                 case 3:
  3589.                     gDateFormatterState = "3";
  3590.                     break;
  3591.             }
  3592.             break;
  3593.         case "FirstDayDigit":
  3594.             switch(gDateDayPosition) {
  3595.                 case 1:
  3596.                     gDateFormatterState = "0.1";
  3597.                     break;
  3598.                 case 2:
  3599.                     gDateFormatterState = "1.1";
  3600.                     break;
  3601.                 case 3:
  3602.                     gDateFormatterState = "2.1";
  3603.                     break;
  3604.             }
  3605.             break;
  3606.         case "SecondDayDigit":
  3607.             switch(gDateDayPosition) {
  3608.                 case 1:
  3609.                     gDateFormatterState = "1";
  3610.                     break;
  3611.                 case 2:
  3612.                     gDateFormatterState = "2";
  3613.                     break;
  3614.                 case 3:
  3615.                     gDateFormatterState = "3";
  3616.                     break;
  3617.             }
  3618.             break;
  3619.         case "FirstYearDigit":
  3620.             switch(gDateYearPosition) {
  3621.                 case 1:
  3622.                     gDateFormatterState = "0.1";
  3623.                     break;
  3624.                 case 2:
  3625.                     gDateFormatterState = "1.1";
  3626.                     break;
  3627.                 case 3:
  3628.                     gDateFormatterState = "2.1";
  3629.                     break;
  3630.             }
  3631.             break;
  3632.         case "SucceedingYearDigit":
  3633.             switch(gDateYearPosition) {
  3634.                 case 1:
  3635.                     gDateFormatterState = "1";
  3636.                     break;
  3637.                 case 2:
  3638.                     if (gDateDayPosition != 0) {
  3639.                         gDateFormatterState = "2";
  3640.                     }
  3641.                     // else if special case of "credit card expiration date field" (i.e., without "day" value), early terminate date formatter
  3642.                     else {
  3643.                         gDateFormatterState = "3";
  3644.                     }
  3645.                     break;
  3646.                 case 3:
  3647.                     gDateFormatterState = "3";
  3648.                     break;
  3649.             }
  3650.             break;
  3651.         case "DisableDateFormatter":
  3652.             gDateFormatterState = "4";
  3653.             break;
  3654.     }   
  3655. }
  3656.  
  3657.  
  3658. /**************************************************************************************
  3659.  *  Function    : processFirstMonthDigit()                                            *
  3660.  *  Description : Parses the first month digit entered.                               *
  3661.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3662.  *                    enters the date string                                          *
  3663.  *                gDateStringEntered, current contents (value) in the input textbox   *
  3664.  *  Returns:    : None.                                                               *
  3665.  *  ISD Feature : "Date Formatter"                                                    *
  3666.  *  Author      : Samson Wong                                                         *
  3667.  **************************************************************************************/
  3668. function processFirstMonthDigit(aInputTextbox, gDateStringEntered) {
  3669.  
  3670.     // myAlert("processFirstMonthDigit(aInputTextbox.value=" + aInputTextbox.value + ",gDateStringEntered=" + gDateStringEntered + ")");
  3671.  
  3672.     var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  3673.  
  3674.     var lValidDigits = "01";
  3675.     // if user entered premature date separator...
  3676.     if ((lLastCharEntered == gDateSeparator1) || (lLastCharEntered == gDateSeparator2)) {
  3677.         clearLastCharEntered(aInputTextbox);
  3678.     }
  3679.     // if "2", "3",..., or "9" entered...
  3680.     else if (lValidDigits.indexOf(lLastCharEntered) == -1) {
  3681.         // pre-pend month's leading "0" for user
  3682.         // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-1) + "0" + lLastCharEntered;
  3683.         aInputTextbox.value = gDateStringEntered + "0" + lLastCharEntered;
  3684.  
  3685.         if (gDateMonthPosition == 1) {
  3686.             aInputTextbox.value += gDateSeparator1;
  3687.         }
  3688.         else if (gDateMonthPosition == 2) {
  3689.             aInputTextbox.value += gDateSeparator2;
  3690.         }
  3691.  
  3692.         // record current valid month entry
  3693.         gCurrentValidDateArray[gDateMonthPosition-1] = "0" + lLastCharEntered;
  3694.     
  3695.         goToNextState("SecondMonthDigit");
  3696.     }
  3697.     // if "0" or "1" entered...
  3698.     else {
  3699.         // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-1) + lLastCharEntered;
  3700.         aInputTextbox.value = gDateStringEntered + lLastCharEntered;
  3701.         
  3702.         // record current valid month entry
  3703.         gCurrentValidDateArray[gDateMonthPosition-1] = lLastCharEntered + "m";
  3704.  
  3705.         goToNextState("FirstMonthDigit");
  3706.     }
  3707. }
  3708.  
  3709.  
  3710. /**************************************************************************************
  3711.  *  Function    : processSecondMonthDigit()                                           *
  3712.  *  Description : Parses the second month digit entered.                              *
  3713.  *  Assumption  : First month digit entered was "0" or "1".                           *
  3714.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3715.  *                    enters the date string                                          *
  3716.  *                gDateStringEntered, current contents (value) in the input textbox   *
  3717.  *  Returns:    : None.                                                               *
  3718.  *  ISD Feature : "Date Formatter"                                                    *
  3719.  *  Author      : Samson Wong                                                         *
  3720.  **************************************************************************************/
  3721. function processSecondMonthDigit(aInputTextbox, gDateStringEntered) {
  3722.     var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  3723.     var lFirstCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-2);
  3724.  
  3725.     // myAlert("processSecondMonthDigit(aInputTextbox.value=" + aInputTextbox.value + ",gDateStringEntered=" + gDateStringEntered + ")");
  3726.  
  3727.     // if user entered premature date separator...
  3728.     if (((gDateMonthPosition == 1) && (lLastCharEntered == gDateSeparator1)) || ((gDateMonthPosition == 2) && (lLastCharEntered == gDateSeparator2))) {
  3729.         // if valid user-entered premature date separator...
  3730.         if (lFirstCharEntered != "0") {
  3731.             // pre-pend month's leading "0" for user
  3732.             // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-2) + "0" + lFirstCharEntered;
  3733.             aInputTextbox.value = gDateStringEntered.substring(0,(gDateStringEntered.length)-1) + "0" + lFirstCharEntered;
  3734.             
  3735.             if (gDateMonthPosition == 1) {
  3736.                 aInputTextbox.value += gDateSeparator1;
  3737.             }
  3738.             else if (gDateMonthPosition == 2) {
  3739.                 aInputTextbox.value += gDateSeparator2;
  3740.             }        
  3741.            
  3742.             // record current valid month entry
  3743.             gCurrentValidDateArray[gDateMonthPosition-1] = "0" + lFirstCharEntered;
  3744.  
  3745.             goToNextState("SecondMonthDigit");
  3746.         }
  3747.         else {
  3748.             clearLastCharEntered(aInputTextbox);
  3749.             
  3750.             // remain in current state      
  3751.         }
  3752.     }
  3753.     // if user entered incorrect premature date separator...
  3754.     else if (((gDateMonthPosition == 1) && (lLastCharEntered == gDateSeparator2)) || ((gDateMonthPosition == 2) && (lLastCharEntered == gDateSeparator1)))
  3755.     {
  3756.         clearLastCharEntered(aInputTextbox);
  3757.         
  3758.         // remain in current state
  3759.     }
  3760.     else if (lFirstCharEntered == "0") {
  3761.         // if valid month portion entered...
  3762.         if (lLastCharEntered != "0") {
  3763.  
  3764.             if (gDateMonthPosition == 1) {
  3765.                 aInputTextbox.value += gDateSeparator1;
  3766.             }
  3767.             else if (gDateMonthPosition == 2) {
  3768.                 aInputTextbox.value += gDateSeparator2;
  3769.             }
  3770.            
  3771.             // record current valid month entry
  3772.             gCurrentValidDateArray[gDateMonthPosition-1] = gCurrentValidDateArray[gDateMonthPosition-1].replace(/m/,lLastCharEntered);
  3773.  
  3774.             goToNextState("SecondMonthDigit");
  3775.         }
  3776.         // invalid month digit entered...
  3777.         else {
  3778.             clearLastCharEntered(aInputTextbox);
  3779.             
  3780.             // remain in current state
  3781.         }
  3782.     }
  3783.     else if (lFirstCharEntered == "1") {
  3784.         var lValidDigits = "012";
  3785.         // if valid month portion entered...                        
  3786.         if (lValidDigits.indexOf(lLastCharEntered) != -1) {
  3787.  
  3788.             if (gDateMonthPosition == 1) {
  3789.                 aInputTextbox.value += gDateSeparator1;
  3790.             }
  3791.             else if (gDateMonthPosition == 2) {
  3792.                 aInputTextbox.value += gDateSeparator2;
  3793.             }
  3794.            
  3795.             // record current valid month entry
  3796.             gCurrentValidDateArray[gDateMonthPosition-1] = gCurrentValidDateArray[gDateMonthPosition-1].replace(/m/,lLastCharEntered);
  3797.  
  3798.             goToNextState("SecondMonthDigit");
  3799.         }
  3800.         // invalid month digit entered...
  3801.         else {
  3802.             clearLastCharEntered(aInputTextbox);
  3803.             
  3804.             // remain in current state
  3805.         }
  3806.     }
  3807. }
  3808.  
  3809.  
  3810. /**************************************************************************************
  3811.  *  Function    : processFirstDayDigit()                                              *
  3812.  *  Description : Parses the first day digit entered.                                 *
  3813.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3814.  *                    enters the date string                                          *
  3815.  *                gDateStringEntered, current contents (value) in the input textbox   *
  3816.  *  Returns:    : None.                                                               *
  3817.  *  ISD Feature : "Date Formatter"                                                    *
  3818.  *  Author      : Samson Wong                                                         *
  3819.  **************************************************************************************/
  3820. function processFirstDayDigit(aInputTextbox, gDateStringEntered) {
  3821.     var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  3822.     
  3823.     // myAlert("processFirstDayDigit(aInputTextbox.value=" + aInputTextbox.value + ",gDateStringEntered=" + gDateStringEntered + ")");
  3824.  
  3825.     var lValidDigits = "0123";
  3826.     if ((lLastCharEntered == gDateSeparator1) || (lLastCharEntered == gDateSeparator2)) {
  3827.         clearLastCharEntered(aInputTextbox);
  3828.     }
  3829.     // if "4", "5",..., or "9" entered...
  3830.     else if (lValidDigits.indexOf(lLastCharEntered) == -1) {
  3831.         // pre-pend month's leading "0" for user
  3832.         // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-1) + "0" + lLastCharEntered;
  3833.         aInputTextbox.value = gDateStringEntered + "0" + lLastCharEntered;
  3834.  
  3835.         if (gDateDayPosition == 1) {
  3836.             aInputTextbox.value += gDateSeparator1;
  3837.         }
  3838.         else if (gDateDayPosition == 2) {
  3839.             aInputTextbox.value += gDateSeparator2;
  3840.         }
  3841.         
  3842.         // record current valid day entry
  3843.         gCurrentValidDateArray[gDateDayPosition-1] = "0" + lLastCharEntered;        
  3844.             
  3845.         goToNextState("SecondDayDigit");
  3846.     }
  3847.     // if "0", "1", "2", or "3" entered...
  3848.     else {
  3849.         // record current valid day entry
  3850.         gCurrentValidDateArray[gDateDayPosition-1] = lLastCharEntered + "d";
  3851.         
  3852.         goToNextState("FirstDayDigit");
  3853.     }
  3854. }
  3855.  
  3856.  
  3857. /**************************************************************************************
  3858.  *  Function    : processSecondDayDigit()                                             *
  3859.  *  Description : Parses the second day digit entered.                                *
  3860.  *  Assumption  : First month digit entered was "0",..., or "3.                       *
  3861.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3862.  *                    enters the date string                                          *
  3863.  *                gDateStringEntered, current contents (value) in the input textbox   *
  3864.  *  Returns:    : None.                                                               *
  3865.  *  ISD Feature : "Date Formatter"                                                    *
  3866.  *  Author      : Samson Wong                                                         *
  3867.  **************************************************************************************/
  3868. function processSecondDayDigit(aInputTextbox, gDateStringEntered) {
  3869.     var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  3870.     var lFirstCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-2);
  3871.  
  3872.     // myAlert("processSecondDayDigit(aInputTextbox.value=" + aInputTextbox.value + ",gDateStringEntered=" + gDateStringEntered + ")");
  3873.     
  3874.     // if user entered premature date separator...
  3875.     if (((gDateDayPosition == 1) && (lLastCharEntered == gDateSeparator1)) || ((gDateDayPosition == 2) && (lLastCharEntered == gDateSeparator2))) {
  3876.         // if valid user-entered premature date separator...
  3877.         if (lFirstCharEntered != "0") {
  3878.             // pre-pend day's leading "0" for user
  3879.             // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-2) + "0" + lFirstCharEntered;
  3880.             aInputTextbox.value = gDateStringEntered.substring(0,(gDateStringEntered.length)-1) + "0" + lFirstCharEntered;
  3881.  
  3882.             if (gDateDayPosition == 1) {
  3883.                 aInputTextbox.value += gDateSeparator1;
  3884.             }   
  3885.             else if (gDateDayPosition == 2) {
  3886.                 aInputTextbox.value += gDateSeparator2;
  3887.             }   
  3888.            
  3889.             // record current valid day entry
  3890.             gCurrentValidDateArray[gDateDayPosition-1] = "0" + lFirstCharEntered;
  3891.             
  3892.             goToNextState("SecondDayDigit");
  3893.         }
  3894.         else {
  3895.             clearLastCharEntered(aInputTextbox);
  3896.             
  3897.             // remain in current state      
  3898.         }
  3899.     }
  3900.     // if user entered incorrect premature date separator...
  3901.     else if (((gDateDayPosition == 1) && (lLastCharEntered == gDateSeparator2)) || ((gDateDayPosition == 2) && (lLastCharEntered == gDateSeparator1)))
  3902.     {
  3903.         clearLastCharEntered(aInputTextbox);
  3904.         
  3905.         // remain in current state
  3906.     }
  3907.     else if (lFirstCharEntered == "0") {
  3908.         // if valid day portion entered...
  3909.         if (lLastCharEntered  != "0") {
  3910.             if (gDateDayPosition == 1) {
  3911.                 aInputTextbox.value += gDateSeparator1;
  3912.             }
  3913.             else if (gDateDayPosition == 2) {
  3914.                 aInputTextbox.value += gDateSeparator2;
  3915.             }
  3916.             
  3917.             // record current valid day entry
  3918.             gCurrentValidDateArray[gDateDayPosition-1] = gCurrentValidDateArray[gDateDayPosition-1].replace(/d/,lLastCharEntered);
  3919.                         
  3920.             goToNextState("SecondDayDigit");
  3921.         }
  3922.         // invalid day digit entered...
  3923.         else {
  3924.             clearLastCharEntered(aInputTextbox);
  3925.             
  3926.             // remain in current state
  3927.         }
  3928.     }
  3929.     else if ( (lFirstCharEntered == "1") ||
  3930.               (lFirstCharEntered == "2") ) {
  3931.             // all second day digits are valid
  3932.             
  3933.             if (gDateDayPosition == 1) {
  3934.                 aInputTextbox.value += gDateSeparator1;
  3935.             }
  3936.             else if (gDateDayPosition == 2) {
  3937.                 aInputTextbox.value += gDateSeparator2;
  3938.             }
  3939.            
  3940.             // record current valid day entry
  3941.             gCurrentValidDateArray[gDateDayPosition-1] = gCurrentValidDateArray[gDateDayPosition-1].replace(/d/,lLastCharEntered);
  3942.                                     
  3943.             goToNextState("SecondDayDigit");
  3944.     }
  3945.     // first day digit is "3"...
  3946.     else {
  3947.         var lValidDigits = "01";
  3948.         // if valid second day portion entered...                       
  3949.         if (lValidDigits.indexOf(lLastCharEntered) != -1) {
  3950.  
  3951.             if (gDateDayPosition == 1) {
  3952.                 aInputTextbox.value += gDateSeparator1;
  3953.             }
  3954.             else if (gDateDayPosition == 2) {
  3955.                 aInputTextbox.value += gDateSeparator2;
  3956.             }
  3957.             
  3958.             // record current valid day entry
  3959.             gCurrentValidDateArray[gDateDayPosition-1] = gCurrentValidDateArray[gDateDayPosition-1].replace(/d/,lLastCharEntered);
  3960.                                                 
  3961.             goToNextState("SecondDayDigit");
  3962.         }
  3963.         // invalid second day digit entered...
  3964.         else {
  3965.             clearLastCharEntered(aInputTextbox);
  3966.             
  3967.             // remain in current state
  3968.         }
  3969.     }
  3970. }
  3971.  
  3972.  
  3973. /**************************************************************************************
  3974.  *  Function    : processFirstYearDigit()                                             *
  3975.  *  Description : Parses the first year digit entered.                                *
  3976.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  3977.  *                    enters the date string                                          *
  3978.  *                gDateStringEntered, current contents (value) in the input textbox   *
  3979.  *  Returns:    : None.                                                               *
  3980.  *  ISD Feature : "Date Formatter"                                                    *
  3981.  *  Author      : Samson Wong                                                         *
  3982.  **************************************************************************************/
  3983. function processFirstYearDigit(aInputTextbox, gDateStringEntered) {
  3984.     var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  3985.         
  3986.     // if four-digit year...
  3987.     if (gDatePatternArray[gDateYearPosition-1].length == 4) {
  3988.         if ((lLastCharEntered == gDateSeparator1) || (lLastCharEntered == gDateSeparator2)) {
  3989.             clearLastCharEntered(aInputTextbox);
  3990.         }
  3991.         // if invalid year digit entered...
  3992.         else if ( (lLastCharEntered != "1") &&
  3993.              (lLastCharEntered != "2") ) {
  3994.             
  3995.             // pre-pend year's leading "20" for user (assume 21st century)
  3996.             // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-1) + "20" + lLastCharEntered;
  3997.             aInputTextbox.value = gDateStringEntered + "20" + lLastCharEntered;
  3998.  
  3999.             // record current valid year entry
  4000.             gCurrentValidDateArray[gDateYearPosition-1] = "20" + lLastCharEntered + "y";    
  4001.         }
  4002.         else {
  4003.             // aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-1) + lLastCharEntered;
  4004.             aInputTextbox.value = gDateStringEntered + lLastCharEntered;
  4005.  
  4006.             // record current valid year entry
  4007.             gCurrentValidDateArray[gDateYearPosition-1] = lLastCharEntered + "yyy"; 
  4008.         }
  4009.     }
  4010.     // if two-digit year...
  4011.     else {
  4012.         if ((lLastCharEntered == gDateSeparator1) || (lLastCharEntered == gDateSeparator2)) {
  4013.             clearLastCharEntered(aInputTextbox);
  4014.         }
  4015.         else {
  4016.             // any initial year digit is valid
  4017.     
  4018.             // record current valid year entry
  4019.             gCurrentValidDateArray[gDateYearPosition-1] = lLastCharEntered + "y";
  4020.         }
  4021.     }   
  4022.     
  4023.     goToNextState("FirstYearDigit");
  4024. }
  4025.  
  4026.  
  4027. /**************************************************************************************
  4028.  *  Function    : processSucceedingYearDigit()                                        *
  4029.  *  Description : Parses subsequent year digits entered.                              *
  4030.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  4031.  *                    enters the date string                                          *
  4032.  *                gDateStringEntered, current contents (value) in the input textbox   *
  4033.  *  Returns:    : None.                                                               *
  4034.  *  ISD Feature : "Date Formatter"                                                    *
  4035.  *  Author      : Samson Wong                                                         *
  4036.  **************************************************************************************/
  4037. function processSucceedingYearDigit(aInputTextbox, gDateStringEntered) {
  4038.     var lLastCharEntered = (aInputTextbox.value).charAt((aInputTextbox.value).length-1);
  4039.  
  4040.     var lDateStringArray;
  4041.     var lYearStringEnteredSoFar;
  4042.     
  4043.     if (gDateSeparator1 == gDateSeparator2)
  4044.     {
  4045.         lDateStringArray = (aInputTextbox.value).split(gDateSeparator1);
  4046.         lYearStringEnteredSoFar = lDateStringArray[gDateYearPosition-1];
  4047.     }
  4048.     else
  4049.     {
  4050.         if (gDateYearPosition == 3)
  4051.         {
  4052.             lDateStringArray = (aInputTextbox.value).split(gDateSeparator2);
  4053.             lYearStringEnteredSoFar = lDateStringArray[1];
  4054.         }
  4055.         else if (gDateYearPosition == 2)
  4056.         {
  4057.             lDateStringArray = (aInputTextbox.value).split(gDateSeparator2);
  4058.             lDateStringArray = lDateStringArray[0].split(gDateSeparator1);
  4059.             lYearStringEnteredSoFar = lDateStringArray[1];        
  4060.         }
  4061.         else // (gDateYearPosition == 1)
  4062.         {
  4063.             lDateStringArray = (aInputTextbox.value).split(gDateSeparator1);
  4064.             lYearStringEnteredSoFar = lDateStringArray[0];
  4065.         }
  4066.     }
  4067.     
  4068.     if ((lLastCharEntered == gDateSeparator1) || (lLastCharEntered == gDateSeparator2)) {
  4069.         clearLastCharEntered(aInputTextbox);
  4070.     }
  4071.     else {  
  4072.         // any subsequent year digit is valid
  4073.         
  4074.         // record current valid year entry
  4075.         gCurrentValidDateArray[gDateYearPosition-1] = gCurrentValidDateArray[gDateYearPosition-1].replace(/y/,lLastCharEntered);        
  4076.     }
  4077.     
  4078.     if (gCurrentValidDateArray[gDateYearPosition-1].indexOf("y") == -1) {
  4079.     
  4080.         if ((gDateYearPosition == 1) && (gDateDayPosition != 0)) {
  4081.             aInputTextbox.value += gDateSeparator1;
  4082.         }
  4083.         else if ((gDateYearPosition == 2) && (gDateDayPosition != 0)) {
  4084.             aInputTextbox.value += gDateSeparator2;
  4085.         }
  4086.  
  4087.         goToNextState("SucceedingYearDigit");
  4088.     }
  4089.     // else, remain in current state
  4090. }
  4091.  
  4092.  
  4093. /**************************************************************************************
  4094.  *  Function    : clearPreviousCharEntered()                                          *
  4095.  *  Description : Clears the previous date digit entered, and adjusts the state       *
  4096.  *                    machine accordingly.                                            *
  4097.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  4098.  *                    enters the date string                                          *
  4099.  *                gDateStringEntered, current contents (value) in the input textbox   *
  4100.  *  Returns:    : None.                                                               *
  4101.  *  ISD Feature : "Date Formatter"                                                    *
  4102.  *  Author      : Samson Wong                                                         *
  4103.  **************************************************************************************/
  4104. function clearPreviousCharEntered(aInputTextbox) {
  4105. /*
  4106.     switch(gDateFormatterState) {
  4107.         case "0.0":
  4108.             break;
  4109.             
  4110.         case "0.1":
  4111.             if (gDateYearPosition ==1) {
  4112.                 // clear previous date digit        
  4113.                 aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-1);
  4114.                 
  4115.                 // reset current valid date string
  4116.                 gCurrentValidDateArray[0].charAt(gDatePatterArray.length-1) = gDatePatternArray[0].charAt(gDatePatterArray.length-1);
  4117.                 
  4118.                 if (gCurrentValidDateArray[0].indexOf() {
  4119.                     // remain in current state machine state
  4120.                     gDateFormatterState = "0.1"
  4121.                 }
  4122.                 else {
  4123.                     // reset state machine state
  4124.                     gDateFormatterState = "0.0"
  4125.                 }
  4126.             }
  4127.             else {
  4128.                 // clear only date digit        
  4129.                 aInputTextbox.value = "";
  4130.                 
  4131.                 // reset current valid date string
  4132.                 gCurrentValidDateArray[0] = gDatePatternArray[0];
  4133.                 
  4134.                 // reset state machine state
  4135.                 gDateFormatterState = "0.0";
  4136.             }
  4137.             break;
  4138.         case "1.0":
  4139.             // clear date separator and last date digit
  4140.             aInputTextbox.value = aInputTextbox.value.substring(0, aInputTextbox.value.length-2);
  4141.  
  4142.             // reset current valid date string
  4143.             gCurrentValidDateArray[0].charAt(gDatePatterArray.length-1) = gDatePatternArray[0].charAt(gDatePatterArray.length-1);
  4144.             
  4145.             // reset state machine state
  4146.             gDateFormatterState = "0.1";
  4147.         
  4148.             break;
  4149.         case "1.1":
  4150.         
  4151.             break;
  4152.         case "2.0":
  4153.         
  4154.             break;
  4155.         case "2.1":
  4156.         
  4157.             break;
  4158.         case "3.0":
  4159.         
  4160.             break;
  4161.     }
  4162. */
  4163. }
  4164.  
  4165.  
  4166. /**************************************************************************************
  4167.  *  Function    : parseDatePattern()                                                  *
  4168.  *  Description : Parses, validates, and records the input date pattern to which the  *
  4169.  *                     user-inputted date string will be formatted.                   *
  4170.  *  Parameters  : aDatePattern, date pattern (should be composed of a combination of  *
  4171.  *                    "m"s, "d"s, "y"s, and "separators").                            *
  4172.  *  Returns:    : true, if date pattern is valid.                                     *
  4173.  *                false, if date pattern is invalid.                                  *
  4174.  *  ISD Feature : "Date Formatter"                                                    *
  4175.  *  Author      : Samson Wong                                                         *
  4176.  **************************************************************************************/
  4177. function parseDatePattern(aInputTextbox, aDatePattern) {
  4178.  
  4179.     var lDatePattern = aDatePattern;
  4180.     //lDatePattern = "yyyy/mm/dd";
  4181.     
  4182.     // initialize global variables
  4183.     initializeDateFormatter(aInputTextbox);
  4184.             
  4185.     // strip all occurrences of "m"s, "d"s, and "y"s
  4186.     lDatePattern = stripChar(lDatePattern, "m");
  4187.     if (lDatePattern != "invalid date pattern") {
  4188.         lDatePattern = stripChar(lDatePattern, "d");
  4189.     }
  4190.     else {
  4191.         return false;
  4192.     }
  4193.     if (lDatePattern != "invalid date pattern") {
  4194.         lDatePattern = stripChar(lDatePattern, "y");
  4195.     }
  4196.     else {
  4197.         return false;
  4198.     }
  4199.     
  4200.     if (lDatePattern == "invalid date pattern") {
  4201.         return false;
  4202.     }
  4203.  
  4204.     // strip extraneous spaces in Hungarian and Slovak date patterns
  4205.     // while (lDatePattern.indexOf(" ") != -1)
  4206.     // {
  4207.     //   lDatePattern = lDatePattern.replace(" ", "");
  4208.     //   aDatePattern = aDatePattern.replace(" ", "");
  4209.     // }
  4210.     
  4211.     // strip extraneous trailing separator in Slovak date pattern
  4212.     // if ((lDatePattern.length == 3) && (lDatePattern.charAt(2) == ".")) {
  4213.     //  lDatePattern = lDatePattern.substring(0,lDatePattern.length-1);
  4214.     //  aDatePattern = aDatePattern.substring(0,aDatePattern.length-1);
  4215.     // }
  4216.     
  4217.     // myAlert("parseDatePattern(lDatePattern=" + lDatePattern + ",aDatePattern=" + aDatePattern + ")");
  4218.             
  4219.     // determine date separator
  4220.     // alert("lDatePattern.length(" + lDatePattern.length + ")");
  4221.     if ((lDatePattern.length == 2) || (lDatePattern.length == 1)) {
  4222.          
  4223.         if (lDatePattern.length == 2)
  4224.         {
  4225.             gDateSeparator1 = lDatePattern.charAt(0);
  4226.              gDateSeparator2 = lDatePattern.charAt(1);
  4227.          }
  4228.          else // (lDatePattern.length == 1)
  4229.          {
  4230.             gDateSeparator1 = lDatePattern.charAt(0);
  4231.              gDateSeparator2 = lDatePattern.charAt(0);
  4232.          }
  4233.        
  4234.         if (gDateSeparator1 == gDateSeparator2)
  4235.         {
  4236.             // split date pattern into date component portions
  4237.             gDatePatternArray = aDatePattern.split(gDateSeparator1);
  4238.         }
  4239.         else // (gDateSeparator1 != gDateSeparator2)
  4240.         {
  4241.             var lTempArray1 = aDatePattern.split(gDateSeparator1);
  4242.             var lDatePortion1 = lTempArray1[0];
  4243.             var lTempArray2 = lTempArray1[1].split(gDateSeparator2);
  4244.             var lDatePortion2 = lTempArray2[0];
  4245.             if (lTempArray2.length == 1)
  4246.             {
  4247.                 gDatePatternArray = new Array(lDatePortion1, lDatePortion2);
  4248.             }
  4249.             else if (lTempArray2.length > 1)
  4250.             {
  4251.                 gDatePatternArray = new Array(lDatePortion1, lDatePortion2, lTempArray2[1]);
  4252.             }
  4253.         }
  4254.         
  4255.         // alert("gDatePatternArray.length(" + gDatePatternArray.length + ")");
  4256.         if ((gDatePatternArray.length == 3) || (gDatePatternArray.length == 2)) {
  4257.  
  4258.             // now that an actual date pattern is being passed in via the event handlers, initialize date portion positions
  4259.             gDateMonthPosition = 0;
  4260.             gDateDayPosition = 0;
  4261.             gDateYearPosition = 0;
  4262.             
  4263.             for (var i=0; i<(gDatePatternArray.length); i++) {
  4264.                 // alert("gDatePatternArray[" + i + "](" + gDatePatternArray[i] + ")");
  4265.                 switch(gDatePatternArray[i].charAt(0)) {
  4266.                     case "m":
  4267.                         gDateMonthPosition = i+1;
  4268.                         break;
  4269.                     case "d":
  4270.                         gDateDayPosition = i+1;
  4271.                         break;
  4272.                     case "y":
  4273.                         gDateYearPosition = i+1;
  4274.                         break;
  4275.                 }
  4276.                 
  4277.                 gCurrentValidDateArray[i] = gDatePatternArray[i];
  4278.             }
  4279.             
  4280.             // alert("parseDatePattern.mdyPositions(" + gDateMonthPosition + "," + gDateDayPosition + "," + gDateYearPosition + ")");
  4281.             // alert("parseDatePattern(gCurrentValidDateArray[0]=" + gCurrentValidDateArray[0] + ",gCurrentValidDateArray[1]=" + gCurrentValidDateArray[1] + ",gCurrentValidDateArray[2]=" + gCurrentValidDateArray[2] + ")");
  4282.             
  4283.             // record date pattern
  4284.             gPreviousDatePattern = aDatePattern;
  4285.  
  4286.             return true;
  4287.         }
  4288.     }
  4289.  
  4290.     // clear recorded date pattern
  4291.     gPreviousDatePattern = "";
  4292.             
  4293.     return false;
  4294. }
  4295.  
  4296.  
  4297. /**************************************************************************************
  4298.  *  Function    : stripChar()                                                         *
  4299.  *  Description : Helper function to removes all occurrences of an alphabetic         *
  4300.  *                     character from an input string.                                *
  4301.  *  Parameters  : pString, date pattern composed of a combination of "m"s, "d"s, and  *
  4302.  *                    "y"s.                                                           *
  4303.  *                pCharToStrip, alphabetic character to be removed from pString.      *
  4304.  *  Returns:    : Original input string with alphabetic character removed.            *
  4305.  *  ISD Feature : "Date Formatter"                                                    *
  4306.  *  Author      : Samson Wong                                                         *
  4307.  **************************************************************************************/
  4308. function stripChar(pString, pCharToStrip) {
  4309.     var indexOfCharToEliminate = -1;
  4310.     var indexOfPreviousCharEliminated = -1;
  4311.     var lDone = false;
  4312.     
  4313.     while (!lDone) {
  4314.         if (pString.length == 0) {
  4315.             lDone = true;
  4316.         }
  4317.         else {
  4318.             indexOfCharToEliminate = pString.indexOf(pCharToStrip);
  4319.  
  4320.             // myAlert("stripChar(pString=" + pString + ",pCharToStrip=" + pCharToStrip + ",indexOfCharToEliminate=" + indexOfCharToEliminate + ")");
  4321.             
  4322.             if (indexOfCharToEliminate == -1) {
  4323.                 lDone = true;
  4324.             }
  4325.             else {
  4326.             
  4327.                 if ( (indexOfPreviousCharEliminated == -1) ||
  4328.                      ((indexOfPreviousCharEliminated != -1) && (indexOfPreviousCharEliminated == indexOfCharToEliminate)) ) {
  4329.                     // remove single character from input string
  4330.                     pString = pString.substring(0, indexOfCharToEliminate) + pString.substring(indexOfCharToEliminate+1, (pString.length));
  4331.                     
  4332.                     // record index of last character eliminated (the next, if any, character to be eliminated must be in the same location
  4333.                     //    as this character removed, i.e., the individual "m"s, "d"s, and "y"s, respectively, must be adjacent to each other,
  4334.                     //    otherwise the date pattern is invalid)
  4335.                     indexOfPreviousCharEliminated = indexOfCharToEliminate;
  4336.                 }
  4337.                 else {
  4338.                     // myAlert("stripCharInvalid(pString=" + pString + ",pCharToStrip=" + pCharToStrip + ")");
  4339.                     return("invalid date pattern");
  4340.                 } 
  4341.             }           
  4342.         }
  4343.     }
  4344.     return(pString);
  4345. }
  4346.  
  4347.  
  4348. /**************************************************************************************
  4349.  *  Function    : clearLastCharEntered()                                              *
  4350.  *  Description : Helper function to remove the last character entered in the input   *
  4351.  *                     textbox.                                                       *
  4352.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  4353.  *                    enters the date string                                          *
  4354.  *  Returns:    : true, if last character successfully removed.                       *
  4355.  *                false, if reference to input textbox invalid.                       *
  4356.  *  ISD Feature : "Date Formatter"                                                    *
  4357.  *  Authors     : Richard Gorremans (xbase@volcano.net), www.spiritwolfx.com, and     *
  4358.  *                    Samson Wong                                                     *
  4359.  **************************************************************************************/
  4360. function clearLastCharEntered(aInputTextbox) {
  4361.  
  4362.     // myAlert("clearLastCharEntered(lastChar=" + aInputTextbox.value.charAt(aInputTextbox.value.length-1) + ")");
  4363.     if (aInputTextbox) {
  4364.         if (isNav4)
  4365.         {
  4366.             aInputTextbox.value = "";
  4367.             aInputTextbox.focus();
  4368.             aInputTextbox.select();
  4369.         }
  4370.         else
  4371.         {
  4372.             if (aInputTextbox.value.length > 1) {
  4373.                 // clear last character, but retain the rest of (previously-entered) date string        
  4374.                 aInputTextbox.value = aInputTextbox.value.substring(0, ((aInputTextbox.value.length)-1));
  4375.             }
  4376.             else {
  4377.                 aInputTextbox.value = "";
  4378.             }
  4379.         }
  4380.         return true;
  4381.     }
  4382.     return false;
  4383. }
  4384.  
  4385.  
  4386. /**************************************************************************************
  4387.  *  Function    : presubmitDateValidation()                                           *
  4388.  *  Description : onblur event handler to determine if date string entered is valid.  *
  4389.  *                    Changes the date textbox's background color to pink if invalid. *
  4390.  *  Parameters  : aInputTextbox, reference to the html textbox into which the user    *
  4391.  *                    enters the date string                                          *
  4392.  *                aDatePattern, date pattern (containing some combination of "m"s,    *
  4393.  *                    "s"s, "y"s, and "separators" to which the user-inputted date    *
  4394.  *                     string is to be formated                                       *
  4395.  *  ISD Feature : "Date Formatter"                                                    *
  4396.  *  Authors     : Samson Wong                                                         *
  4397.  **************************************************************************************/
  4398. function presubmitDateValidation(aInputTextbox, aDatePattern) {
  4399.     var lInputTextboxArray;
  4400.     var lDatePatternArray;
  4401.     var lDateMonthString;
  4402.     var lDateDayString;
  4403.     var lDateYearString;
  4404.     var lValidDigits;   
  4405.     var lDateValid = true; // assume valid date string unless discovered otherwise
  4406.  
  4407.     // myAlert("presubmitDateValidation(aInputTextbox.value=" + aInputTextbox.value + ",aDatePattern=" + aDatePattern + ")");
  4408.     // myAlert("presubmitDateValidation(gPreviousDatePattern=" + gPreviousDatePattern + ",aDatePattern=" + aDatePattern + ")");
  4409.     
  4410.     // re-parse date pattern only if different from that in previous call
  4411.     if (gPreviousDatePattern != aDatePattern) {
  4412.     
  4413.         // parse date pattern
  4414.         if (!parseDatePattern(aInputTextbox, aDatePattern)) {
  4415.             goToNextState("DisableDateFormatter");
  4416.             return false;
  4417.         }       
  4418.     }
  4419.     
  4420.     if (aInputTextbox.value.length > 0) {
  4421.         if (gDateSeparator1 == gDateSeparator2)
  4422.         {
  4423.             // split date pattern into date component portions
  4424.             lDatePatternArray = aDatePattern.split(gDateSeparator1);
  4425.             lInputTextboxArray = aInputTextbox.value.split(gDateSeparator1);
  4426.         }
  4427.         else // (gDateSeparator1 != gDateSeparator2)
  4428.         {
  4429.             lDatePatternArray = new Array(3);
  4430.             var lTempArray1 = aDatePattern.split(gDateSeparator1);
  4431.             lDatePatternArray[0] = lTempArray1[0];
  4432.             var lTempArray2 = lTempArray1[1].split(gDateSeparator2);
  4433.             lDatePatternArray[1] = lTempArray2[0];
  4434.             lDatePatternArray[2] = lTempArray2[1];
  4435.             
  4436.             lInputTextboxArray = new Array(3);
  4437.             var lTempArray1 = aInputTextbox.value.split(gDateSeparator1);
  4438.             lInputTextboxArray[0] = lTempArray1[0];
  4439.             var lTempArray2 = lTempArray1[1].split(gDateSeparator2);
  4440.             lInputTextboxArray[1] = lTempArray2[0];
  4441.             lInputTextboxArray[2] = lTempArray2[1];
  4442.             
  4443.         }
  4444.  
  4445.  
  4446.         if (lDatePatternArray.length != lInputTextboxArray.length) {
  4447.             lDateValid = false;
  4448.         }
  4449.         
  4450.         if (lDatePatternArray.length == 3) {
  4451.             // extract individual month, day, and year strings
  4452.             switch(gDateMonthPosition) {
  4453.                 case 1:
  4454.                     lDateMonthString = lInputTextboxArray[0];
  4455.                     break;
  4456.                 case 2:
  4457.                     lDateMonthString = lInputTextboxArray[1];
  4458.                     break;
  4459.                 case 3:
  4460.                     lDateMonthString = lInputTextboxArray[2];
  4461.                     break;
  4462.             }
  4463.             switch(gDateDayPosition) {
  4464.                 case 1:
  4465.                     lDateDayString = lInputTextboxArray[0];
  4466.                     break;
  4467.                 case 2:
  4468.                     lDateDayString = lInputTextboxArray[1];
  4469.                     break;
  4470.                 case 3:
  4471.                     lDateDayString = lInputTextboxArray[2];
  4472.                     break;
  4473.             }
  4474.             switch(gDateYearPosition) {
  4475.                 case 1:
  4476.                     lDateYearString = lInputTextboxArray[0];
  4477.                     break;
  4478.                 case 2:
  4479.                     lDateYearString = lInputTextboxArray[1];
  4480.                     break;
  4481.                 case 3:
  4482.                     lDateYearString = lInputTextboxArray[2];
  4483.                     break;
  4484.             }
  4485.             
  4486.             // myAlert("lDateMonthString(" + lDateMonthString + ")");
  4487.             // myAlert("lDateDayString(" + lDateDayString + ")");
  4488.             // myAlert("lDateYearString(" + lDateYearString + ")");
  4489.             
  4490.             // validate month string
  4491.             if ((lDateMonthString != null) && (lDateMonthString.length <= 2)) {
  4492.                 // if two digit month string...
  4493.                 if (lDateMonthString.length == 2) {
  4494.                     // if first digit is "0"...
  4495.                     if (lDateMonthString.charAt(0) == "0") {
  4496.                         lValidDigits = "123456789";
  4497.                         // if second digit is not "1"-"9"...
  4498.                         if (lValidDigits.indexOf(lDateMonthString.charAt(1)) == -1) {
  4499.                             lDateValid = false;
  4500.                         }
  4501.                     }
  4502.                     // if first digit is "1"...
  4503.                     else if (lDateMonthString.charAt(0) == "1") {
  4504.                         lValidDigits = "012";
  4505.                         // if second digit is not "0"-"2"...
  4506.                         if (lValidDigits.indexOf(lDateMonthString.charAt(1)) == -1) {
  4507.                             lDateValid = false;
  4508.                         }
  4509.                     }
  4510.                     // invalid first month digit
  4511.                     else {
  4512.                         lDateValid = false;
  4513.                     }
  4514.                 }
  4515.                 // if single digit month string...
  4516.                 else if (lDateMonthString.length == 1) {
  4517.                     lValidDigits = "123456789";
  4518.                     // if single digit is not "1"-"9"...
  4519.                     if (lValidDigits.indexOf(lDateMonthString.charAt(0)) == -1) {
  4520.                         lDateValid = false;
  4521.                     }
  4522.                 }
  4523.                 // zero-lengthed month string (i.e., consecutive date separators in date textbox)
  4524.                 else {
  4525.                     lDateValid = false;
  4526.                 }
  4527.             }
  4528.             // too many characters in month string
  4529.             else {
  4530.                 lDateValid = false;
  4531.             }
  4532.  
  4533.             // validate day string
  4534.             if ((lDateDayString != null) && (lDateDayString.length <= 2)) {
  4535.                 // if two digit day string...
  4536.                 if (lDateDayString.length == 2) {
  4537.                     // if first digit is "0"...
  4538.                     if (lDateDayString.charAt(0) == "0") {
  4539.                         lValidDigits = "123456789";
  4540.                         // if second digit is not "1"-"9"...
  4541.                         if (lValidDigits.indexOf(lDateDayString.charAt(1)) == -1) {
  4542.                             lDateValid = false;
  4543.                         }
  4544.                     }
  4545.                     // if first digit is "1" or "2"...
  4546.                     else if ((lDateDayString.charAt(0) == "1") || (lDateDayString.charAt(0) == "2")) {
  4547.                         lValidDigits = "0123456789";
  4548.                         // if second digit is not "0"-"9"...
  4549.                         if (lValidDigits.indexOf(lDateDayString.charAt(1)) == -1) {
  4550.                             lDateValid = false;
  4551.                         }
  4552.                     }
  4553.                     // if first digit is "3"...
  4554.                     else if (lDateDayString.charAt(0) == "3") {
  4555.                         lValidDigits = "01";
  4556.                         // if second digit is not "0" or "1"...
  4557.                         if (lValidDigits.indexOf(lDateDayString.charAt(1)) == -1) {
  4558.                             lDateValid = false;
  4559.                         }
  4560.                     }
  4561.                     // invalid first day digit
  4562.                     else {
  4563.                         lDateValid = false;
  4564.                     }
  4565.                 }
  4566.                 // if single digit day string...
  4567.                 else if (lDateDayString.length == 1) {
  4568.                     lValidDigits = "123456789";
  4569.                     // if single digit is not "1"-"9"...
  4570.                     if (lValidDigits.indexOf(lDateDayString.charAt(0)) == -1) {
  4571.                         lDateValid = false;
  4572.                     }
  4573.                 }
  4574.                 // zero-lengthed day string (i.e., consecutive date separators in date textbox)
  4575.                 else {
  4576.                     lDateValid = false;
  4577.                 }
  4578.             }
  4579.             // too many digits in day string
  4580.             else {
  4581.                 lDateValid = false;
  4582.             }
  4583.             
  4584.             // validate year string
  4585.             if ((lDateYearString != null) && (lDateYearString.length != 2) && (lDateYearString.length != 4)) {
  4586.                 lDateValid = false;
  4587.             }
  4588.         }
  4589.         // special case of "credit card expiration date"...
  4590.         else if (lDatePatternArray.length == 2) {
  4591.             lInputTextboxArray = aInputTextbox.value.split(gDateSeparator1);
  4592.  
  4593.             // extract individual month and year strings
  4594.             lDateMonthString = lInputTextboxArray[0];
  4595.             lDateYearString = lInputTextboxArray[1];
  4596.             
  4597.             // myAlert("lDateMonthString(" + lDateMonthString + ")");
  4598.             // myAlert("lDateYearString(" + lDateYearString + ")");
  4599.             
  4600.             // validate month string
  4601.             if ((lDateMonthString != null) && (lDateMonthString.length <= 2)) {
  4602.                 // if two digit month string...
  4603.                 if (lDateMonthString.length == 2) {
  4604.                     // if first digit is "0"...
  4605.                     if (lDateMonthString.charAt(0) == "0") {
  4606.                         lValidDigits = "123456789";
  4607.                         // if second digit is not "1"-"9"...
  4608.                         if (lValidDigits.indexOf(lDateMonthString.charAt(1)) == -1) {
  4609.                             lDateValid = false;
  4610.                         }
  4611.                     }
  4612.                     // if first digit is "1"...
  4613.                     else if (lDateMonthString.charAt(0) == "1") {
  4614.                         lValidDigits = "012";
  4615.                         // if second digit is not "0"-"2"...
  4616.                         if (lValidDigits.indexOf(lDateMonthString.charAt(1)) == -1) {
  4617.                             lDateValid = false;
  4618.                         }
  4619.                     }
  4620.                     // invalid first month digit
  4621.                     else {
  4622.                         lDateValid = false;
  4623.                     }
  4624.                 }
  4625.                 // if single digit month string...
  4626.                 else if (lDateMonthString.length == 1) {
  4627.                     lValidDigits = "123456789";
  4628.                     // if single digit is not "1"-"9"...
  4629.                     if (lValidDigits.indexOf(lDateMonthString.charAt(0)) == -1) {
  4630.                         lDateValid = false;
  4631.                     }
  4632.                 }
  4633.                 // zero-lengthed month string (i.e., consecutive date separators in date textbox)
  4634.                 else {
  4635.                     lDateValid = false;
  4636.                 }
  4637.             }
  4638.             // too many characters in month string
  4639.             else {
  4640.                 lDateValid = false;
  4641.             }
  4642.             
  4643.             // validate year string
  4644.             if ((lDateYearString != null) && (lDateYearString.length != 2) && (lDateYearString.length != 4)) {
  4645.                 lDateValid = false;
  4646.             }
  4647.         }
  4648.         else {
  4649.             lDateValid = false;
  4650.         }
  4651.         
  4652.         /*
  4653.         if (lDateValid == false) {
  4654.             // change date text field background color to pink
  4655.             aInputTextbox.style.background = "pink";
  4656.         }
  4657.         */
  4658.     }
  4659.     
  4660.     if (lDateValid == false) {
  4661.         // clear recorded date pattern
  4662.         gPreviousDatePattern = "";
  4663.     }
  4664.     
  4665.     return(lDateValid);          
  4666. }
  4667.  
  4668.  
  4669. function updateTarget(targetName, selectedValue, selectedDisplayValue)
  4670.     {
  4671.         if (window.opener && !window.opener.closed) {
  4672.             var target = window.opener.document.getElementById(targetName);
  4673.             
  4674.             // sam - always replace last dropdown list entry before selecting entry via Fev_SetFormControlValue()
  4675.             // because Firefox/Netscape does not support adding additional entries
  4676.             // var bSuccess = Fev_SetFormControlValue(target, selectedValue);
  4677.             var bSuccess = false;
  4678.             
  4679.             if (!bSuccess)
  4680.             {
  4681.                 // sam - replace last dropdown list entry (instead inserting a new list item) because Firefox/Netscape
  4682.                 // does not support adding additional entries
  4683.                 if ( /* insertListControlValue(window.opener.document, target, selectedValue, selectedDisplayValue) || */
  4684.                     Fev_ReplaceLastListControlOption(target, selectedValue, selectedDisplayValue) )
  4685.                 {
  4686.                     //try setting the selection again
  4687.                     bSuccess = Fev_SetFormControlValue(target, selectedValue);
  4688.                 }
  4689.             }
  4690.             
  4691.             if (bSuccess)
  4692.             {
  4693.                 if(target != null) {
  4694.                     if (navigator.appName == "Netscape") {
  4695.                         var myevent = document.createEvent("HTMLEvents")
  4696.                         myevent.initEvent("change", true, true)
  4697.                         target.dispatchEvent(myevent);
  4698.                     }
  4699.                     else { // IE
  4700.                         target.fireEvent('onchange');
  4701.                     }
  4702.                 }
  4703.             }           
  4704.  
  4705.             window.close();
  4706.         }
  4707.     }
  4708.  
  4709.     /******************************************************************************************************/
  4710.     /* sam - this function should only be used for IE (Firefox/Netscape does not support "options.add()") *
  4711.     /******************************************************************************************************/
  4712.     //Inserts the value into a list element, independent of the element's type.
  4713.     function insertListControlValue(objDocument, objListElement, strValue, strText)
  4714.     {
  4715.         var strTagName = Fev_GetElementTagName(objListElement);
  4716.         switch (strTagName.toLowerCase())
  4717.         {
  4718.             case "select":
  4719.                 var objOption = objDocument.createElement("OPTION");
  4720.                 objOption.value = strValue;
  4721.                 objOption.text = strText;
  4722.                 objListElement.options.add(objOption);
  4723.                 return true;
  4724.                 break;
  4725.             default:
  4726.                 break;
  4727.         }
  4728.         return false;
  4729.     }
  4730.  
  4731.  
  4732. /**************************************************************************************
  4733.  *  Description : Global variables used by "JavaScript Date Selector" feature.        *
  4734.  *  ISD Feature : "JavaScript Date Selector"                                          *
  4735.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  4736.  **************************************************************************************/
  4737. var dateSelectorDivID = "dateSelector";
  4738. var iFrameDivID = "dateSelectoriframe";
  4739.  
  4740. var dayArrayShort = new Array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa');
  4741. var dayArrayMed = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
  4742. var dayArrayLong = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
  4743. var monthArrayShort = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
  4744. var monthArrayMed = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec');
  4745. var monthArrayLong = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
  4746.  
  4747. // these variables define the date formatting we're expecting and outputting.
  4748. // If you want to use a different format by default, change the defaultDateSeparator
  4749. // and defaultDateFormat variables either here or on your HTML page.
  4750. var defaultDateSeparator = "/";        // common values would be "/" or "."
  4751. var defaultDateFormat = "mdy"    // valid values are "mdy", "dmy", and "ymd"
  4752. var dateSeparator = defaultDateSeparator;
  4753. var dateFormat = defaultDateFormat;
  4754.  
  4755.  
  4756. /**************************************************************************************
  4757.  *  Function    : displayDateSelector()                                               *
  4758.  *  Description : Displays the date selector beneath the "date input field" when the  *
  4759.  *                     "date selector icon" is clicked.                               *
  4760.  *  Parameters  : dateFieldName, html element name of the "date input field" that     *
  4761.  *                     will be filled in if the user picks a date                     *
  4762.  *                displayBelowThisObject, html element name of the object below which *
  4763.  *                     the date selector is displayed (optional)                      *
  4764.  *  Returns:    : None.                                                               *
  4765.  *  ISD Feature : "JavaScript Date Selector"                                          *
  4766.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  4767.  **************************************************************************************/
  4768. function displayDateSelector(dateFieldName, displayBelowThisObject, dtFormat, dtSep)
  4769. {
  4770.   var targetDateField = document.getElementsByName (dateFieldName).item(0);
  4771.  
  4772.   // if we weren't told what node to display the dateSelector beneath, just display it
  4773.   // beneath the date field we're updating
  4774.   if (!displayBelowThisObject)
  4775.     displayBelowThisObject = targetDateField;
  4776.  
  4777.   // if a date separator character was given, update the dateSeparator variable
  4778.   if (dtSep)
  4779.     dateSeparator = dtSep;
  4780.   else
  4781.     dateSeparator = defaultDateSeparator;
  4782.  
  4783.   // if a date format was given, update the dateFormat variable
  4784.   if (dtFormat)
  4785.     dateFormat = dtFormat;
  4786.   else
  4787.     dateFormat = defaultDateFormat;
  4788.  
  4789.   var x = displayBelowThisObject.offsetLeft;
  4790.   var y = displayBelowThisObject.offsetTop + displayBelowThisObject.offsetHeight ;
  4791.  
  4792.   // deal with elements inside tables and such
  4793.   var parent = displayBelowThisObject;
  4794.   while (parent.offsetParent) {
  4795.     parent = parent.offsetParent;
  4796.     x += parent.offsetLeft;
  4797.     y += parent.offsetTop ;
  4798.   }
  4799.  
  4800.   drawDateSelector(targetDateField, x, y);
  4801. }
  4802.  
  4803.  
  4804. /**************************************************************************************
  4805.  *  Function    : drawDateSelector()                                                  *
  4806.  *  Description : Called by displayDateSelector() to draw the dateSelector object     *
  4807.  *                (which is just a table with calendar elements) at the specified x   *
  4808.  *                and y coordinates.                                                  *
  4809.  *  Parameters  : targetDateField, html element name of the "date input field" that   *
  4810.  *                     will be filled in if the user picks a date                     *
  4811.  *                x, x-coordinate of the displayed date selector                      *
  4812.  *                y, y-coordinate of the displayed date selector                      *
  4813.  *  Returns:    : None.                                                               *
  4814.  *  ISD Feature : "JavaScript Date Selector"                                          *
  4815.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  4816.  **************************************************************************************/
  4817. function drawDateSelector(targetDateField, x, y)
  4818. {
  4819.   var dt = getFieldDate(targetDateField.value );
  4820.  
  4821.   // the dateSelector table will be drawn inside of a <div> with an ID defined by the
  4822.   // global dateSelectorDivID variable. If such a div doesn't yet exist on the HTML
  4823.   // document we're working with, add one.
  4824.   if (!document.getElementById(dateSelectorDivID)) {
  4825.     // don't use innerHTML to update the body, because it can cause global variables
  4826.     // that are currently pointing to objects on the page to have bad references
  4827.     //document.body.innerHTML += "<div id='" + dateSelectorDivID + "' class='dpDiv'></div>";
  4828.     var newNode = document.createElement("div");
  4829.     newNode.setAttribute("id", dateSelectorDivID);
  4830.     newNode.setAttribute("class", "dpDiv");
  4831.     newNode.setAttribute("style", "visibility: hidden;");
  4832.     document.body.appendChild(newNode);
  4833.   }
  4834.  
  4835.   // move the dateSelector div to the proper x,y coordinate and toggle the visiblity
  4836.   var selectorDiv = document.getElementById(dateSelectorDivID);
  4837.   selectorDiv.style.position = "absolute";
  4838.   selectorDiv.style.left = x + "px";
  4839.   selectorDiv.style.top = y + "px";
  4840.   selectorDiv.style.visibility = (selectorDiv.style.visibility == "visible" ? "hidden" : "visible");
  4841.   selectorDiv.style.display = (selectorDiv.style.display == "" ? "none" : "");
  4842.   selectorDiv.style.zIndex = 10000;
  4843.  
  4844.   // draw the dateSelector table
  4845.   refreshDateSelector(targetDateField.name, dt.getFullYear(), dt.getMonth(), dt.getDate());
  4846. }
  4847.  
  4848.  
  4849. /**************************************************************************************
  4850.  *  Function    : refreshDateSelector()                                               *
  4851.  *  Description : Function which actually does the drawing of the date selector       *
  4852.  *                    html table.                                                     *
  4853.  *  Parameters  : dateFieldName, html element name of the "date input field" that     *
  4854.  *                     will be filled in if the user picks a date                     *
  4855.  *                year, year to highlight (optional) (default is today's year)        *
  4856.  *                month, month to highlight (optional) (default is today's month)     *
  4857.  *                day, day to highlight (optional) (default is today's day)           *
  4858.  *  Returns:    : None.                                                               *
  4859.  *  ISD Feature : "JavaScript Date Selector"                                          *
  4860.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  4861.  **************************************************************************************/
  4862. function refreshDateSelector(dateFieldName, year, month, day)
  4863. {
  4864.   // if no arguments are passed, use today's date; otherwise, month and year
  4865.   // are required (if a day is passed, it will be highlighted later)
  4866.   var thisDay = new Date();
  4867.  
  4868.   if ((month >= 0) && (year > 0)) {
  4869.     thisDay = new Date(year, month, 1);
  4870.   } else {
  4871.     day = thisDay.getDate();
  4872.     thisDay.setDate(1);
  4873.   }
  4874.  
  4875.   // the calendar will be drawn as a table
  4876.   // you can customize the table elements with a global CSS style sheet,
  4877.   // or by hardcoding style and formatting elements below
  4878.   var crlf = "\r\n";
  4879.   var TABLE = "<table cols=7 class='dpTable'>" + crlf;
  4880.   var xTABLE = "</table>" + crlf;
  4881.   var TR = "<tr class='dpTR'>";
  4882.   var TR_title = "<tr class='dpTitleTR'>";
  4883.   var TR_days = "<tr class='dpDayTR'>";
  4884.   var TR_todaybutton = "<tr class='dpTodayButtonTR'>";
  4885.   var xTR = "</tr>" + crlf;
  4886.   var TD = "<td class='dpTD' onMouseOut='this.className=\"dpTD\";' onMouseOver=' this.className=\"dpTDHover\";' ";    // leave this tag open, because we'll be adding an onClick event
  4887.   // sam
  4888.   var TD_noDay = "<td>";
  4889.   // sam
  4890.   // var TD_title = "<td colspan=5 class='dpTitleTD'>";
  4891.   var TD_title = "<td colspan=3 class='dpTitleTD'>";
  4892.   // var TD_buttons = "<td class='dpButtonTD'>";
  4893.   var TD_buttons = "<td class='dpButtonTD' colspan='2' style='text-align:center;'>";
  4894.   var TD_todaybutton = "<td colspan=7 class='dpTodayButtonTD'>";
  4895.   var TD_days = "<td class='dpDayTD'>";
  4896.   var TD_selected = "<td class='dpDayHighlightTD' onMouseOut='this.className=\"dpDayHighlightTD\";' onMouseOver='this.className=\"dpTDHover\";' ";    // leave this tag open, because we'll be adding an onClick event
  4897.   var xTD = "</td>" + crlf;
  4898.   var DIV_title = "<div class='dpTitleText'>";
  4899.   var DIV_selected = "<div class='dpDayHighlight'>";
  4900.   var xDIV = "</div>";
  4901.  
  4902.   // start generating the code for the calendar table
  4903.   var html = TABLE;
  4904.  
  4905.   // this is the title bar, which displays the month and the buttons to
  4906.   // go back to a previous month or forward to the next month
  4907.   html += TR_title;
  4908.   
  4909.   // sam
  4910.   html += TD_buttons + getButtonCode(dateFieldName, thisDay, -12, "arrow_beg.gif") + " " + getButtonCode(dateFieldName, thisDay, -1, "arrow_left.gif") + xTD;
  4911.   html += TD_title + DIV_title + monthArrayLong[ thisDay.getMonth()] + " " + thisDay.getFullYear() + xDIV + xTD;
  4912.   html += TD_buttons + getButtonCode(dateFieldName, thisDay, 1, "arrow_right.gif") + " " + getButtonCode(dateFieldName, thisDay, 12, "arrow_end.gif") + xTD;
  4913.   html += xTR;
  4914.  
  4915.   // this is the row that indicates which day of the week we're on
  4916.   html += TR_days;
  4917.   for(i = 0; i < dayArrayShort.length; i++)
  4918.     html += TD_days + dayArrayShort[i] + xTD;
  4919.   html += xTR;
  4920.  
  4921.   // now we'll start populating the table with days of the month
  4922.   html += TR;
  4923.  
  4924.   // first, the leading blanks
  4925.   for (i = 0; i < thisDay.getDay(); i++)
  4926.     html += TD_noDay + " " + xTD;
  4927.  
  4928.   // now, the days of the month
  4929.   do {
  4930.     dayNum = thisDay.getDate();
  4931.     TD_onclick = " onclick=\"updateDateField('" + dateFieldName + "', '" + getDateString(thisDay) + "');\">";
  4932.     
  4933.     if (dayNum == day)
  4934.       html += TD_selected + TD_onclick + DIV_selected + dayNum + xDIV + xTD;
  4935.     else
  4936.       html += TD + TD_onclick + dayNum + xTD;
  4937.     
  4938.     // if this is a Saturday, start a new row
  4939.     if (thisDay.getDay() == 6)
  4940.       html += xTR + TR;
  4941.     
  4942.     // increment the day
  4943.     thisDay.setDate(thisDay.getDate() + 1);
  4944.   } while (thisDay.getDate() > 1)
  4945.  
  4946.   // fill in any trailing blanks
  4947.   if (thisDay.getDay() > 0) {
  4948.     for (i = 6; i > thisDay.getDay(); i--)
  4949.       html += TD_noDay + " " + xTD;
  4950.   }
  4951.   html += xTR;
  4952.  
  4953.   // add a button to allow the user to easily return to today, or close the calendar
  4954.   var today = new Date();
  4955.   var todayString = "Today is " + dayArrayMed[today.getDay()] + ", " + monthArrayMed[ today.getMonth()] + " " + today.getDate();
  4956.   html += TR_todaybutton + TD_todaybutton;
  4957.   
  4958.   // sam
  4959.   // html += "<button class='dpTodayButton' onClick='refreshDateSelector(\"" + dateFieldName + "\");'>this month</button> ";
  4960.     html += "<table cellpadding='0' cellspacing='0' border='0' style='padding-top:10px;' width='100%'>"
  4961.     html += "        <tr><td style='text-align:right;'>";
  4962.   
  4963.     html += "<table cellpadding='0' cellspacing='0' border='0'>"
  4964.     html += "        <tr>";
  4965.     html += "           <td class='button-TL-white'><img src='../Images/space.gif' height='5' width='17' alt=''/></td>";
  4966.     html += "           <td class='button-T-white'><img src='../Images/space.gif' height='5' width='4' alt=''/></td>";
  4967.     html += "           <td class='button-TR-white'><img src='../Images/space.gif' height='5' width='16' alt=''/></td>";
  4968.     html += "        </tr>";
  4969.     html += "        <tr>";
  4970.     html += "           <td class='button-L-white'><img src='../Images/space.gif' height='12' width='17' alt=''/></td>";
  4971.     html += "           <td class='button-white'><a id='OkButton__Button' class='button_link' href='#' onClick='refreshDateSelector(\"" + dateFieldName + "\");'>Today</a></td>";
  4972.     html += "           <td class='button-R-white'><img src='../Images/space.gif' height='12' width='16' alt=''/></td>";
  4973.     html += "        </tr>";
  4974.     html += "        <tr>";
  4975.     html += "           <td class='button-BL-white'><img src='../Images/space.gif' height='8' width='17' alt=''/></td>";
  4976.     html += "           <td class='button-B-white'><img src='../Images/space.gif' height='8' width='4' alt=''/></td>";
  4977.     html += "           <td class='button-BR-white'><img src='../Images/space.gif' height='8' width='16' alt=''/></td>";
  4978.     html += "        </tr>";
  4979.     html += "       </table>";
  4980.  
  4981.     html += "        </td>";
  4982.     html += "       <td width='10'>";
  4983.     html += "        </td>";
  4984.     html += "       <td>";
  4985.  
  4986.     html += "<table cellpadding='0' cellspacing='0' border='0'>"
  4987.     html += "        <tr>";
  4988.     html += "           <td class='button-TL-white'><img src='../Images/space.gif' height='5' width='17' alt=''/></td>";
  4989.     html += "           <td class='button-T-white'><img src='../Images/space.gif' height='5' width='4' alt=''/></td>";
  4990.     html += "           <td class='button-TR-white'><img src='../Images/space.gif' height='5' width='16' alt=''/></td>";
  4991.     html += "        </tr>";
  4992.     html += "        <tr>";
  4993.     html += "           <td class='button-L-white'><img src='../Images/space.gif' height='12' width='17' alt=''/></td>";
  4994.     html += "           <td class='button-white'><a id='CancelButton__Button' class='button_link' href='#' onClick='updateDateField(\"" + dateFieldName + "\");'>Cancel</a></td>";
  4995.     html += "           <td class='button-R-white'><img src='../Images/space.gif' height='12' width='16' alt=''/></td>";
  4996.     html += "        </tr>";
  4997.     html += "        <tr>";
  4998.     html += "           <td class='button-BL-white'><img src='../Images/space.gif' height='8' width='17' alt=''/></td>";
  4999.     html += "           <td class='button-B-white'><img src='../Images/space.gif' height='8' width='4' alt=''/></td>";
  5000.     html += "           <td class='button-BR-white'><img src='../Images/space.gif' height='8' width='16' alt=''/></td>";
  5001.     html += "        </tr>";
  5002.     html += "       </table>";
  5003.  
  5004.     html += "        </td></tr>";
  5005.     html += "       </table>";
  5006.     
  5007.   // html += "<button class='dpTodayButton' onClick='updateDateField(\"" + dateFieldName + "\");'>close</button>";
  5008.   html += xTD + xTR;
  5009.  
  5010.   // and finally, close the table
  5011.   html += xTABLE;
  5012.  
  5013.   document.getElementById(dateSelectorDivID).innerHTML = html;
  5014.   // add an "iFrame shim" to allow the dateSelector to display above selection lists
  5015.   adjustiFrame();
  5016. }
  5017.  
  5018.  
  5019. /**************************************************************************************
  5020.  *  Function    : getButtonCode()                                                     *
  5021.  *  Description : Helper function to construct the html for the previous/next         *
  5022.  *                    month/year buttons.                                             *
  5023.  *  Parameters  : dateFieldName, html element name of the "date input field" that     *
  5024.  *                     will be filled in if the user picks a date                     *
  5025.  *                dateVal, current date highlighted                                   *
  5026.  *                adjust, number of months to move back/forward                       *
  5027.  *                label, previous/next month/year button image to use for this button *
  5028.  *  Returns:    : The html for previous/next month/year button.                       *
  5029.  *  ISD Feature : "JavaScript Date Selector"                                          *
  5030.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  5031.  **************************************************************************************/
  5032. function getButtonCode(dateFieldName, dateVal, adjust, label)
  5033. {
  5034.   var newMonth = (dateVal.getMonth () + adjust) % 12;
  5035.   var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);
  5036.   if (newMonth < 0) {
  5037.     newMonth += 12;
  5038.     newYear += -1;
  5039.   }
  5040.  
  5041.   // sam
  5042.   // return "<button class='dpButton' onClick='refreshDateSelector(\"" + dateFieldName + "\", " + newYear + ", " + newMonth + ");'>" + label + "</button>";
  5043.   return "<a href='#' onClick='refreshDateSelector(\"" + dateFieldName + "\", " + newYear + ", " + newMonth + ");'><img src='../Images/" + label + "' border='0'></a>"
  5044. }
  5045.  
  5046.  
  5047. /**************************************************************************************
  5048.  *  Function    : getDateString()                                                     *
  5049.  *  Description : Convert a JavaScript Date object to a string, based on the          *
  5050.  *                dateFormat and dateSeparator variables at the beginning of this     *
  5051.  *                script library.                                                     *
  5052.  *  Parameters  : dateVal, current date highlighted                                   *
  5053.  *  Returns:    : The highlighted date as a string.                                   *
  5054.  *  ISD Feature : "JavaScript Date Selector"                                          *
  5055.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  5056.  **************************************************************************************/
  5057. function getDateString(dateVal)
  5058. {
  5059.   var dayString = "00" + dateVal.getDate();
  5060.   var monthString = "00" + (dateVal.getMonth()+1);
  5061.   dayString = dayString.substring(dayString.length - 2);
  5062.   monthString = monthString.substring(monthString.length - 2);
  5063.  
  5064.   switch (dateFormat) {
  5065.     case "dmy" :
  5066.       return dayString + dateSeparator + monthString + dateSeparator + dateVal.getFullYear();
  5067.     case "ymd" :
  5068.       return dateVal.getFullYear() + dateSeparator + monthString + dateSeparator + dayString;
  5069.     case "mdy" :
  5070.     default :
  5071.       return monthString + dateSeparator + dayString + dateSeparator + dateVal.getFullYear();
  5072.   }
  5073. }
  5074.  
  5075.  
  5076. /**************************************************************************************
  5077.  *  Function    : getFieldDate()                                                      *
  5078.  *  Description : Converts a string to a JavaScript Date objec                        *
  5079.  *  Parameters  : dateString, date string to be converted into a JavaScript Date      *
  5080.  *                    object.                                                         *
  5081.  *  Returns:    : The date string as a JavaScript Date object.                        *
  5082.  *  ISD Feature : "JavaScript Date Selector"                                          *
  5083.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  5084.  **************************************************************************************/
  5085. function getFieldDate(dateString)
  5086. {
  5087.   var dateVal;
  5088.   var dArray;
  5089.   var d, m, y;
  5090.  
  5091.   try {
  5092.     dArray = splitDateString(dateString);
  5093.     if (dArray) {
  5094.       switch (dateFormat) {
  5095.         case "dmy" :
  5096.           d = parseInt(dArray[0], 10);
  5097.           m = parseInt(dArray[1], 10) - 1;
  5098.           y = parseInt(dArray[2], 10);
  5099.           break;
  5100.         case "ymd" :
  5101.           d = parseInt(dArray[2], 10);
  5102.           m = parseInt(dArray[1], 10) - 1;
  5103.           y = parseInt(dArray[0], 10);
  5104.           break;
  5105.         case "mdy" :
  5106.         default :
  5107.           d = parseInt(dArray[1], 10);
  5108.           m = parseInt(dArray[0], 10) - 1;
  5109.           y = parseInt(dArray[2], 10);
  5110.           break;
  5111.       }
  5112.       dateVal = new Date(y, m, d);
  5113.     } else if (dateString) {
  5114.       dateVal = new Date(dateString);
  5115.     } else {
  5116.       dateVal = new Date();
  5117.     }
  5118.   } catch(e) {
  5119.     dateVal = new Date();
  5120.   }
  5121.  
  5122.   return dateVal;
  5123. }
  5124.  
  5125.  
  5126. /**************************************************************************************
  5127.  *  Function    : splitDateString()                                                   *
  5128.  *  Description : Splits a date string into an array of elements, using common date   *
  5129.  *                    separators.                                                     *
  5130.  *  Parameters  : dateString, date string to be converted into a JavaScript Date      *
  5131.  *                    object.                                                         *
  5132.  *  Returns:    : The split date array, if operation successful; false, otherwise.    *
  5133.  *  ISD Feature : "JavaScript Date Selector"                                          *
  5134.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  5135.  **************************************************************************************/
  5136. function splitDateString(dateString)
  5137. {
  5138.   var dArray;
  5139.   if (dateString.indexOf("/") >= 0)
  5140.     dArray = dateString.split("/");
  5141.   else if (dateString.indexOf(".") >= 0)
  5142.     dArray = dateString.split(".");
  5143.   else if (dateString.indexOf("-") >= 0)
  5144.     dArray = dateString.split("-");
  5145.   else if (dateString.indexOf("\\") >= 0)
  5146.     dArray = dateString.split("\\");
  5147.   else
  5148.     dArray = false;
  5149.  
  5150.   return dArray;
  5151. }
  5152.  
  5153.  
  5154. /**************************************************************************************
  5155.  *  Function    : dateSelectorClosed()                                                *
  5156.  *  Description : Update the "date input field" with the date string, and hide the    *
  5157.  *                    date selector.  If no date string is passed, just close the     *
  5158.  *                    date selector without changing the field value.                 *
  5159.  *  Parameters  : dateFieldName, html element name of the "date input field" that     *
  5160.  *                    will be filled in if the user picks a date                      *
  5161.  *                dateString, date string with which the "date input field" is to be  *
  5162.  *                    updated.                                                        *
  5163.  *  Returns:    : None.                                                               *
  5164.  *  ISD Feature : "JavaScript Date Selector"                                          *
  5165.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  5166.  **************************************************************************************/
  5167. /**
  5168. If the page developer has defined a function called dateSelectorClosed anywhere on
  5169. the page or in an imported library, we will attempt to run that function with the updated
  5170. field as a parameter. This can be used for such things as date validation, setting default
  5171. values for related fields, etc. For example, you might have a function like this to validate
  5172. a start date field:
  5173.  
  5174. function dateSelectorClosed(dateField)
  5175. {
  5176.   var dateObj = getFieldDate(dateField.value);
  5177.   var today = new Date();
  5178.   today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
  5179.  
  5180.   if (dateField.name == "StartDate") {
  5181.     if (dateObj < today) {
  5182.       // if the date is before today, alert the user and display the dateSelector again
  5183.       alert("Please enter a date that is today or later");
  5184.       dateField.value = "";
  5185.       document.getElementById(dateSelectorDivID).style.visibility = "visible";
  5186.       adjustiFrame();
  5187.     } else {
  5188.       // if the date is okay, set the EndDate field to 7 days after the StartDate
  5189.       dateObj.setTime(dateObj.getTime() + (7 * 24 * 60 * 60 * 1000));
  5190.       var endDateField = document.getElementsByName ("EndDate").item(0);
  5191.       endDateField.value = getDateString(dateObj);
  5192.     }
  5193.   }
  5194. }
  5195.  
  5196. */
  5197. function updateDateField(dateFieldName, dateString)
  5198. {
  5199.   var targetDateField = document.getElementsByName (dateFieldName).item(0);
  5200.   if (dateString)
  5201.     targetDateField.value = dateString;
  5202.  
  5203.   var selectorDiv = document.getElementById(dateSelectorDivID);
  5204.   selectorDiv.style.visibility = "hidden";
  5205.   selectorDiv.style.display = "none";
  5206.  
  5207.   adjustiFrame();
  5208.   targetDateField.focus();
  5209.  
  5210.   // after the dateSelector has closed, optionally run a user-defined function called
  5211.   // dateSelectorClosed, passing the field that was just updated as a parameter
  5212.   // (note that this will only run if the user actually selected a date from the dateSelector)
  5213.   if ((dateString) && (typeof(dateSelectorClosed) == "function"))
  5214.     dateSelectorClosed(targetDateField);
  5215. }
  5216.  
  5217.  
  5218. /**************************************************************************************
  5219.  *  Function    : adjustiFrame()                                                      *
  5220.  *  Description : Uses an "iFrame shim" to deal with problems where the dateSelector  *
  5221.  *                    shows up behind selection list elements, if they're below the   *
  5222.  *                    date selector.                                                  *
  5223.  *                The problem and solution are described at:                          *
  5224.  *                 http://dotnetjunkies.com/WebLog/jking/archive/2003/07/21/488.aspx  *
  5225.  *                 http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx *
  5226.  *  Parameters  : selectorDiv, html div containing date selector                      *
  5227.  *                iFrameDiv, html div containing iframe shim.                         *
  5228.  *  Returns:    : None.                                                               *
  5229.  *  ISD Feature : "JavaScript Date Selector"                                          *
  5230.  *  Authors     : Julian Robichaux, http://www.nsftools.com, and Samson Wong          *
  5231.  **************************************************************************************/
  5232. function adjustiFrame(selectorDiv, iFrameDiv)
  5233. {
  5234.   // we know that Opera doesn't like something about this, so if we
  5235.   // think we're using Opera, don't even try
  5236.   var is_opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
  5237.   if (is_opera)
  5238.     return;
  5239.   
  5240.   // put a try/catch block around the whole thing, just in case
  5241.   try {
  5242.     if (!document.getElementById(iFrameDivID)) {
  5243.       // don't use innerHTML to update the body, because it can cause global variables
  5244.       // that are currently pointing to objects on the page to have bad references
  5245.       //document.body.innerHTML += "<iframe id='" + iFrameDivID + "' src='javascript:false;' scrolling='no' frameborder='0'>";
  5246.       var newNode = document.createElement("iFrame");
  5247.       newNode.setAttribute("id", iFrameDivID);
  5248.       newNode.setAttribute("src", "javascript:false;");
  5249.       newNode.setAttribute("scrolling", "no");
  5250.       newNode.setAttribute ("frameborder", "0");
  5251.       document.body.appendChild(newNode);
  5252.     }
  5253.     
  5254.     if (!selectorDiv)
  5255.       selectorDiv = document.getElementById(dateSelectorDivID);
  5256.     if (!iFrameDiv)
  5257.       iFrameDiv = document.getElementById(iFrameDivID);
  5258.     
  5259.     try {
  5260.       iFrameDiv.style.position = "absolute";
  5261.       iFrameDiv.style.width = selectorDiv.offsetWidth;
  5262.       iFrameDiv.style.height = selectorDiv.offsetHeight ;
  5263.       iFrameDiv.style.top = selectorDiv.style.top;
  5264.       iFrameDiv.style.left = selectorDiv.style.left;
  5265.       iFrameDiv.style.zIndex = selectorDiv.style.zIndex - 1;
  5266.       iFrameDiv.style.visibility = selectorDiv.style.visibility ;
  5267.       iFrameDiv.style.display = selectorDiv.style.display;
  5268.     } catch(e) {
  5269.     }
  5270.  
  5271.   } catch (ee) {
  5272.   }
  5273. }
  5274.  
  5275.  
  5276. /**************************************************************************************
  5277.  *  Function    : DisplayPopupWindowCallBackWith11()                                  *
  5278.  *  Description : Displays a popup window with the content received from Ajax method  *
  5279.  *                    of .NET 1.1 application                                           *
  5280.  *  Parameters  : result is the data recieved from ajax method                        *        
  5281.  *  Assumptions : Only Ajax method will call this                                     *
  5282.  *  ISD Feature :                                                                     *
  5283.  *  Authors     : Sowmya.                                                             *
  5284.  **************************************************************************************/
  5285.  
  5286. function PopupDisplayWindowCallBackWith11(result)
  5287. {
  5288.     // The detailRollOverPopup() displays the content returned from the AJAX call in a popup window 
  5289.     // It accepts three parameters: 
  5290.     // - aTitle, string to be displayed in the title bar of the popup window.
  5291.     // - aContent, string containing HTML to be displayed in the body of the popup. 
  5292.     // - aPersist, boolean indicating whether the popup should remain visible even on mouseout.
  5293.     
  5294.     detailRolloverPopup(result.value[0], result.value[1], result.value[2], result.value[3], result.value[4], result.value[5]); 
  5295. }
  5296.  
  5297.  
  5298.  
  5299. /**************************************************************************************
  5300.  *  Function    : DisplayPopupWindowCallBackWith20()                                  *
  5301.  *  Description : Displays a popup window with the content received from Ajax method  *
  5302.  *                    of .NET 2.0 application                                              *
  5303.  *  Parameters  : result is the data recieved from ajax method                        *        
  5304.  *  Assumptions : Only Ajax method will call this                                     *
  5305.  *  ISD Feature :                                                                     *
  5306.  *  Authors     : Sowmya.                                                             *
  5307.  **************************************************************************************/
  5308.  
  5309. function PopupDisplayWindowCallBackWith20(result)
  5310. {
  5311.     // The detailRollOverPopup() displays the content returned from the AJAX call in a popup window 
  5312.     // It accepts three parameters: 
  5313.     // - aTitle, string to be displayed in the title bar of the popup window.
  5314.     // - aContent, string containing HTML to be displayed in the body of the popup. 
  5315.     // - aPersist, boolean indicating whether the popup should remain visible even on mouseout.
  5316.     
  5317.         detailRolloverPopup(result[0], result[1], result[2], result[3], result[4], result[5]);  
  5318. }
  5319.  
  5320. function FCKUpdateLinkedField(id)
  5321. {
  5322.     try
  5323.     {
  5324.         if(typeof(FCKeditorAPI) == "object")
  5325.         {
  5326.             FCKeditorAPI.GetInstance(id).UpdateLinkedField();
  5327.         }
  5328.     }
  5329.     catch(err)
  5330.     {
  5331.     }
  5332. }
  5333.