home *** CD-ROM | disk | FTP | other *** search
/ ftp.tcs3.com / ftp.tcs3.com.tar / ftp.tcs3.com / DRIVERS / Audio / Office2010 / ProPlus.WW / ProPsWW2.cab / SUBMIT.JS < prev    next >
Text File  |  2007-02-04  |  49KB  |  1,490 lines

  1. // Global variables.
  2. var g_RecordID = null;
  3. var g_Record = null;
  4. var g_SelectedID = null;
  5. var g_ModifyRecord = false;
  6. var g_ElementsEnabled = true;
  7. var g_IsPreviewLayout = false;
  8. var g_IsPreviewPane = false;
  9. var g_IsLayout = false;
  10. var g_IsSearch = false;
  11. var g_IsNewRecord = false;
  12. var g_IsResponse = false;
  13. var g_HasDesignChanged = false;
  14. var g_NoEdit = false;
  15. var g_CreateAnother = false;
  16. var g_objDispatch = getScriptDispatch();
  17. var g_arrRichText = new Array();
  18. var g_AttachmentsElement = null;
  19. var g_AttachmentsObject = null;
  20. var g_Initialized = false;
  21.  
  22. // Capture keydown and contextmenu events for the document.
  23. document.onkeydown = keyDownEvent;
  24. document.oncontextmenu = contextMenuEvent;
  25.  
  26. // === keyDownEvent() ==============
  27. // event handler for key down action
  28. function keyDownEvent()
  29. {
  30.     // Return false for backspace key, otherwise do nothing.
  31.     var intKeyCode = event.keyCode;
  32.     var objElement = event.srcElement;
  33.     var strTagName = objElement.tagName;
  34.  
  35.     // Only allow backspace for <input type=text>, <input type=password> and <textarea> objects.
  36.     var blnNoBackspace = true;
  37.     if (strTagName == "TEXTAREA" || (strTagName == "INPUT" && (objElement.type == "text" || objElement.type == "password")))
  38.         blnNoBackspace = false;
  39.  
  40.     // Capture Backspace, Ctrl+N, and Ctrl+P keystrokes to disable them.
  41.     if (intKeyCode == 8 && blnNoBackspace || (event.ctrlKey && (intKeyCode == 78 || intKeyCode == 80)))
  42.         event.returnValue = false;
  43. }
  44.  
  45. // === contextMenuEvent() ==============
  46. // event handler for context menu action
  47. function contextMenuEvent()
  48. {
  49.     // Right-click context menu will only appear if 'Ctrl' key is held down.
  50.     if (!event.ctrlKey)
  51.         event.returnValue = false;
  52. }
  53.  
  54. // === GrooveField(string, string) ============
  55. // object used to define each field in the form
  56. function GrooveField(i_Name, i_Value)
  57. {
  58.     this.name = i_Name;
  59.     this.value = i_Value;
  60. }
  61.  
  62. // === GrooveElement(string, object) =======================
  63. // object used to defined each object type field in the form
  64. function GrooveElement(i_Name, i_Element)
  65. {
  66.     this.name = i_Name;
  67.     this.element = i_Element;
  68. }
  69.  
  70. // === getMultiValue(object, string) ==============
  71. // get the string value from a multiselect list box
  72. function getMultiValue(i_objForm, i_strName)
  73. {
  74.     var strResult = "";
  75.     for (var i = 0; i < i_objForm.elements[i_strName].length; i++)
  76.     {
  77.         if (i_objForm.elements[i_strName].options[i].selected)
  78.         {
  79.             if (i_objForm.elements[i_strName].options[i].value != "")
  80.                 strResult += i_objForm.elements[i_strName].options[i].value + ",";
  81.             else
  82.                 strResult += i_objForm.elements[i_strName].options[i].text + ",";
  83.         }
  84.     }
  85.     return strResult.substr(0, (strResult.length) - 1);
  86. }
  87.  
  88. // === initBackground() =========================================
  89. // set the form background image from attributes on the style tag
  90. function initBackground()
  91. {
  92.     var objFormTheme = document.getElementById("grooveFormTheme");
  93.     if (objFormTheme)
  94.     {
  95.         var strBasePath = g_objDispatch.GetBasePath();
  96.         var strImage = objFormTheme.getAttribute("IMAGE");
  97.         var strRepeat = objFormTheme.getAttribute("REPEAT");
  98.         var strAttachment = objFormTheme.getAttribute("ATTACHMENT");
  99.         var strPosition = objFormTheme.getAttribute("POSITION");
  100.  
  101.         if (strImage != null)
  102.             document.body.style.backgroundImage = "url(" + strBasePath + strImage + ")";
  103.         if (strRepeat != null)
  104.             document.body.style.backgroundRepeat = strRepeat;
  105.         if (strAttachment != null)
  106.             document.body.style.backgroundAttachment = strAttachment;
  107.         if (strPosition != null)
  108.             document.body.style.backgroundPosition = strPosition;
  109.     }
  110. }
  111.  
  112. // === initSystemFields(bool) ======================
  113. // set the values of the system fields if they exist
  114. function initSystemFields(i_blnNew)
  115. {
  116.     var divAuthor = document.getElementById("_SystemAuthor");
  117.     var divCreated = document.getElementById("_SystemCreated");
  118.     var divModified = document.getElementById("_SystemModified");
  119.  
  120.     if (!g_IsPreviewLayout)
  121.     {
  122.         if (!i_blnNew && (typeof g_Record == "string" || g_Record == null))
  123.             return;
  124.  
  125.         if (divAuthor)
  126.         {
  127.             divAuthor.style.fontWeight = "bold";
  128.             divAuthor.style.fontStyle = "italic";
  129.             if (i_blnNew)
  130.                 divAuthor.innerText = g_objDispatch.GetCurrentAuthorName();
  131.             else
  132.                 divAuthor.innerText = g_objDispatch.GetAuthorNameFromRecord(g_Record);
  133.         }
  134.  
  135.         if (divCreated)
  136.         {
  137.             divCreated.style.fontWeight = "bold";
  138.             divCreated.style.fontStyle = "italic";
  139.             if (i_blnNew)
  140.                 divCreated.innerText = g_objDispatch.GetFormattedDate(new Date().valueOf());
  141.             else
  142.             {
  143.                 if (g_Record.HasField("_Created"))
  144.                     divCreated.innerText = g_objDispatch.GetFormattedDate(g_Record.OpenField("_Created"));
  145.             }
  146.         }
  147.  
  148.         if (divModified)
  149.         {
  150.             divModified.style.fontWeight = "bold";
  151.             divModified.style.fontStyle = "italic";
  152.             if (i_blnNew)
  153.                 divModified.innerText = g_objDispatch.GetFormattedDate(new Date().valueOf());
  154.             else
  155.             {
  156.                 if (g_Record.HasField("_Modified"))
  157.                     divModified.innerText = g_objDispatch.GetFormattedDate(g_Record.OpenField("_Modified"));
  158.             }
  159.         }
  160.     }
  161.     else if (g_IsSearch)
  162.     {
  163.         if (divAuthor)
  164.             divAuthor.innerHTML = "<INPUT TYPE=\"text\" NAME=\"_CreatedBy\" />";
  165.         if (divCreated)
  166.             divCreated.innerHTML = "<SPAN NAME=\"_Created\" FormatDateShortFormat=\"M/d/yyyy\"><INPUT TYPE=\"text\" NAME=\"_Created\" DataType=\"Date\" /><BUTTON ONCLICK=\"doCalendar(this)\" STYLE=\"margin-left:5px; width:100px;\" CLASS=\"button\">Calendar...</BUTTON></SPAN>";
  167.         if (divModified)
  168.             divModified.innerHTML = "<SPAN NAME=\"_Modified\" FormatDateShortFormat=\"M/d/yyyy\"><INPUT TYPE=\"text\" NAME=\"_Modified\" DataType=\"Date\" /><BUTTON ONCLICK=\"doCalendar(this)\" STYLE=\"margin-left:5px; width:100px;\" CLASS=\"button\">Calendar...</BUTTON></SPAN>";
  169.     }
  170. }
  171.  
  172. // === initFormPage(integer) ==========
  173. // called when page is finished loading
  174. function initFormPage(i_RecordID)
  175. {
  176.     if (g_objDispatch == null)
  177.         return false;
  178.  
  179.     // Set the background of the window according to the theme chosen.
  180.     initBackground();
  181.  
  182.     // Enable all of the form elements on the page.
  183.     disableFormElements(false);
  184.  
  185.     // Get base form for use throughout the function.
  186.     var DocumentForm = getDocumentForm();
  187.  
  188.     // Clean up the form elements for display.
  189.     if (typeof i_RecordID == "undefined")
  190.         cleanUpFormElements();
  191.  
  192.     if (window.location.search != "")
  193.     {
  194.         if (typeof i_RecordID != "undefined")
  195.         {
  196.             g_RecordID = i_RecordID;
  197.         }
  198.         else
  199.         {
  200.             // Get global variables from the documents querystring.
  201.             getQueryStringVariables();
  202.         }
  203.  
  204.         // Hide the print button if professional license does not exist.
  205.         if (!g_IsPreviewLayout && typeof DocumentForm.PrintButton != "undefined" && typeof DocumentForm.PrintButton.style != "undefined" && !g_objDispatch.DoesGrooveStandardLicenseExistFromAccount(g_objDispatch.g_Account))
  206.             DocumentForm.PrintButton.style.display = "none";
  207.  
  208.         // Check early on to see if this is a response and if so, if it is valid to create a response
  209.         if (g_IsResponse && !g_IsPreviewPane)
  210.         {
  211.             // First check to see if we have a record which has been highlighted and if not, error out and go back to home....
  212.             if (g_SelectedID == "-1" || g_objDispatch.GetRecordByRecordID(g_SelectedID) == null)
  213.             {
  214.                 g_objDispatch.OKMessageBox("You must select a valid parent document in order to create a response.", "Invalid Selection");
  215.                 g_objDispatch.LoadHomePage();
  216.                 return;
  217.             }
  218.  
  219.             // Will add the following to R3 of Forms based on new UI choices
  220.             /*
  221.             // Second, check to see if the record selected is also a response.  If it is, we can put up a warning as well since in most
  222.             // cases responses will not be allowed to responses.
  223.  
  224.             if (g_SelectedID != -1)
  225.             {
  226.                 // get the selected record.
  227.                 var SelectedFormURL = g_objDispatch.GetFormUrlByRecordID(g_SelectedID);
  228.                 
  229.                 var BindableFormURL = String(window.location.href);
  230.                 if (BindableFormURL.indexOf("?") >= 0)
  231.                     BindableFormURL = BindableFormURL.substring(0, BindableFormURL.indexOf("?"));
  232.                 var ThisFormURL = BindableFormURL;
  233.                 
  234.                 // Normalize the urls by converting to lowercase for comparison
  235.                 if (SelectedFormURL.toLowerCase() == ThisFormURL.toLowerCase())
  236.                 {
  237.                     g_objDispatch.OKMessageBox("You must select a valid parent document in order to create a response. You have a response selected.", "Invalid Selection");
  238.                     g_objDispatch.LoadHomePage();
  239.                     return;
  240.                 }
  241.             }
  242.             */
  243.         }
  244.  
  245.  
  246.         // Pass out document to be used by glue code.
  247.         if (g_IsPreviewPane)
  248.             g_objDispatch.SetCurrentPreviewDocument(document);
  249.  
  250.         // Hide or show the submit buttons depending on what the user is doing.
  251.         if ((g_IsPreviewLayout && !g_IsLayout) || g_IsPreviewPane)
  252.             document.getElementById("SubmitBase").style.display = "none";
  253.  
  254.         // Set forms glue global variable for command bar.
  255.         if (!g_IsPreviewPane && !g_IsPreviewLayout)
  256.             g_objDispatch.SetOnFormPage(true);
  257.  
  258.         if (g_IsSearch)
  259.         {
  260.             // Display values of system fields on form.
  261.             initSystemFields(true);
  262.             // If it is a search form, blank out all values.
  263.             clearAllFormValues(true);
  264.         }
  265.         else if (g_RecordID)
  266.         {
  267.             // Get the record from the record id that was passed in.
  268.             g_Record = g_objDispatch.GetRecordByRecordID(g_RecordID);
  269.             // If it is a search form, blank out all values.
  270.             clearAllFormValues(false);
  271.             // Set-up the form with the values stored in the record.
  272.             initFormWithRecord(g_Record, false);
  273.         }
  274.         else
  275.         {
  276.             // Display values of system fields on form.
  277.             initSystemFields(true);
  278.             // Create a new record if there is no record id.
  279.             if (!g_IsLayout && !g_IsPreviewLayout)
  280.                 createNewRecord();
  281.  
  282.             // Set-up the form with the values stored in the record.
  283.             initFormWithRecord(g_Record, true);
  284.         }
  285.     }
  286.     else
  287.     {
  288.         // Hide the print button if professional license does not exist.
  289.         if (typeof DocumentForm.PrintButton != "undefined" && typeof DocumentForm.PrintButton.style != "undefined" && !g_objDispatch.DoesGrooveStandardLicenseExistFromAccount(g_objDispatch.g_Account))
  290.             DocumentForm.PrintButton.style.display = "none";
  291.         // Show the Save, Reset, and Cancel buttons.
  292.         document.getElementById("SubmitBase").style.display = "block";
  293.         // Set forms glue global variable for command bar.
  294.         g_objDispatch.SetOnFormPage(true);
  295.         // Display values of system fields on form.
  296.         initSystemFields(true);
  297.         // Create a new record if there is no querystring.
  298.         createNewRecord();
  299.     }
  300.  
  301.     // Disable the form elements if they are supposed to be.
  302.     disableFormElements(true);
  303.  
  304.     // Set-up some specialized fields and set focus to first form element.
  305.     if (!g_IsPreviewLayout)
  306.         setupSpecializedFields();
  307.  
  308.     if (!g_NoEdit)
  309.     {
  310.         // Make the 'Save and Create Another' button visible if supported.
  311.         var objTdApplyButton = document.getElementById("tdApplyButton");
  312.         if (objTdApplyButton != null)
  313.             objTdApplyButton.style.display = "block";
  314.     }
  315.  
  316.     // Make the 'Print' button visible if supported.
  317.     var objTdPrintButton = document.getElementById("tdPrintButton");
  318.     if (objTdPrintButton != null)
  319.         objTdPrintButton.style.display = "block";
  320.  
  321.     try
  322.     {
  323.         CustomInitialize();
  324.     }
  325.     catch (error)
  326.     {
  327.     }
  328.     
  329.     g_Initialized = true;
  330. }
  331.  
  332. // === terminateFormPage() ===============================
  333. // called when the form is unloaded, for script developers
  334. function terminateFormPage()
  335. {
  336.     // Set forms glue global variable for command bar.
  337.     g_objDispatch.SetOnFormPage(false);
  338.  
  339.     try
  340.     {
  341.         CustomTerminate();
  342.     }
  343.     catch (error)
  344.     {
  345.     }
  346. }
  347.  
  348. // === submitData() =================================
  349. // called when user wants to save form data as record
  350. function submitData()
  351. {
  352.     if (g_IsLayout)
  353.         return false;
  354.  
  355.     var DocumentForm = getDocumentForm();
  356.  
  357.     // Blur all of the elements to check their validation.
  358.     for (var i = 0 ; i < DocumentForm.length; i++)
  359.     {
  360.         DocumentForm.elements[i].fireEvent("onblur");
  361.     }
  362.  
  363.     // Check error array to see if there are still uncorrected errors.
  364.     for (var i = 0; i < g_arrError.length; i++)
  365.     {
  366.         if (typeof g_arrError[i] != "undefined")
  367.         {
  368.             window.setTimeout("g_objDispatch.OKMessageBox('The form values you have entered are not valid. Please correct the error as displayed in the form.', 'Invalid Form Values')", 10);
  369.             g_CreateAnother = false;
  370.             return false;
  371.         }
  372.     }
  373.  
  374.     // This routine submits the form data to Groove.
  375.     var FieldStringEnum = new Array();
  376.     var FieldElementEnum = new Array();
  377.     var FieldCount = 0;
  378.     var lastobjname = "";
  379.     for (var i = 0; i < DocumentForm.length; i++)
  380.     {
  381.         var DocumentElement = DocumentForm.elements[i];
  382.         if (DocumentElement.type == "text" || DocumentElement.type == "password" || DocumentElement.type == "textarea")
  383.         {
  384.             var ElementValue = DocumentElement.value;
  385.             var ElementName = DocumentElement.name;
  386.  
  387.             var strDataType = DocumentElement.getAttribute("DataType");
  388.             if (strDataType != null && strDataType == "Numeric")
  389.             {
  390.                 ElementName = ElementName + "|~|Numeric";
  391.                 if (ElementValue != "")
  392.                     ElementValue = getValidNumber(ElementValue);
  393.             }
  394.             else if (strDataType != null && strDataType == "Date")
  395.             {
  396.                 var strParentName = DocumentElement.parentElement.getAttribute("NAME");
  397.                 if (strParentName != null)
  398.                     ElementName = strParentName + "|~|Date";
  399.  
  400.                 var intDateFormat = g_objDispatch.GrooveIntlDateFormatStyle_Short;
  401.                 var strDateFormat = DocumentElement.parentElement.getAttribute("FormatDateShortFormat");
  402.                 if (strDateFormat == null || strDateFormat == "")
  403.                 {
  404.                     strDateFormat = DocumentElement.parentElement.getAttribute("FormatDateLongFormat");
  405.                     intDateFormat = g_objDispatch.GrooveIntlDateFormatStyle_Full;
  406.                 }
  407.  
  408.                 if (ElementValue != "")
  409.                 {
  410.                     var ElementDate = new Date(getValidDateMillis(ElementValue, strDateFormat, intDateFormat));
  411.                     if (!isNaN(ElementDate))
  412.                     {
  413.                         if (!g_IsPreviewLayout && ElementDate.getHours() == 0 && ElementDate.getMinutes() == 0 && ElementDate.getSeconds() == 0)
  414.                             ElementDate.setHours(12, 0, 0);
  415.                         ElementValue = ElementDate.valueOf();
  416.                     }
  417.                     else
  418.                         ElementValue = "";
  419.                 }
  420.             }
  421.             else
  422.                 ElementName = ElementName + "|~|String";
  423.  
  424.             FieldStringEnum[FieldCount] = new GrooveField(ElementName, ElementValue);
  425.             FieldCount++;
  426.         }
  427.         else if (DocumentElement.type == "select-one")
  428.         {
  429.             if (DocumentElement.selectedIndex >= 0)
  430.             {
  431.                 var objname = DocumentElement.name;
  432.                 var objvalue = DocumentElement.options[DocumentElement.selectedIndex].value;
  433.                 FieldStringEnum[FieldCount] = new GrooveField(objname, objvalue);
  434.                 FieldCount++;
  435.             }
  436.         }
  437.         else if (DocumentElement.type == "select-multiple")
  438.         {
  439.             if (DocumentElement.selectedIndex >= 0)
  440.             {
  441.                 var multobjname = DocumentElement.name;
  442.                 var multobjvalue = getMultiValue(DocumentForm, multobjname);
  443.                 FieldStringEnum[FieldCount] = new GrooveField(multobjname, multobjvalue);
  444.                 FieldCount++;
  445.             }
  446.         }
  447.         else if (DocumentElement.type == "radio")
  448.         {
  449.             var radioobjname = DocumentElement.name;
  450.             var selectedIndex = null;
  451.             if (lastobjname != radioobjname)
  452.             {
  453.                 var radiogroup = DocumentForm.elements[radioobjname];
  454.                 for (var j = 0; j < radiogroup.length; j++)
  455.                 {
  456.                     if (radiogroup[j].checked)
  457.                         selectedIndex = j;
  458.                 }
  459.             
  460.                 if (selectedIndex != null)
  461.                 {
  462.                     FieldStringEnum[FieldCount] = new GrooveField(radioobjname, radiogroup[selectedIndex].value);
  463.                     FieldCount++;
  464.                 }
  465.                 lastobjname = radioobjname;
  466.             }
  467.         }
  468.         else if (DocumentElement.type == "checkbox")
  469.         {
  470.             var checkobjname = DocumentElement.name;
  471.         
  472.             if (DocumentForm.elements[checkobjname].checked)
  473.             {
  474.                 // The checkbox is checked, return a value ('on' by default) if it exists.
  475.                 if (DocumentElement.value == "on")
  476.                     FieldStringEnum[FieldCount] = new GrooveField(checkobjname, "true");
  477.                 else
  478.                     FieldStringEnum[FieldCount] = new GrooveField(checkobjname, DocumentElement.value);
  479.                 FieldCount++;
  480.             }
  481.             else
  482.             {
  483.                 // The checkbox is not checked, return null string.
  484.                 FieldStringEnum[FieldCount] = new GrooveField(checkobjname, "");
  485.                 FieldCount++;
  486.             }
  487.         }
  488.     }
  489.  
  490.     if (g_IsResponse)
  491.     {
  492.         FieldStringEnum[FieldCount] = new GrooveField("_ParentID"+ "|~|Numeric", g_SelectedID);
  493.         FieldCount++;
  494.     }
  495.  
  496.     if (g_AttachmentsObject && !g_IsSearch)
  497.     {
  498.         var count = g_objDispatch.GetAttachmentCount(g_AttachmentsElement);
  499.         FieldStringEnum[FieldCount] = new GrooveField("FileIcon" + "|~|Long", count > 0 ? 1 : 0);
  500.         FieldCount++;
  501.     }
  502.  
  503.     // Submit the values for groove objects (usually rich text) on the page.
  504.     for (var i = 0; i < g_arrRichText.length; i++)
  505.     {
  506.         if (g_IsSearch)
  507.         {
  508.             // If this is a search, get the plain text out of the rich text object.
  509.             var PlainText = getPlainText(g_arrRichText[i]);
  510.             PlainText = PlainText.replace(/^\s*/, "");
  511.             PlainText = PlainText.replace(/\s*$/, "");
  512.             // Need to add a carriage return to the end of the string because the RTF component
  513.             // adds one by default so when we search there will always be a carriage return in the 
  514.             // collection.
  515.             if (PlainText != "")
  516.             {
  517.                 //PlainText = PlainText + "\n";
  518.                 FieldStringEnum[FieldCount] = new GrooveField(g_arrRichText[i].getAttribute("Name"), PlainText);
  519.                 FieldCount++;
  520.             }
  521.         }
  522.         else
  523.         {
  524.             // If this is a form, get the rich text element out of the rich text object.
  525.             var TempElement = g_objDispatch.GetRichTextElement();
  526.             g_arrRichText[i].CellContent.WriteContentToElement(TempElement);
  527.             FieldElementEnum[i] = new GrooveElement(g_arrRichText[i].getAttribute("Name"), TempElement);
  528.         }
  529.     }
  530.  
  531.     // We can NEVER store bindable URLs.  They don't work cross device
  532.     // Therefore we need to get the canonical url from the bindable url.
  533.     // We will need to do the reverse when we need to bind the other way.
  534.     var BindableFormURL = String(window.location.href);
  535.     if (BindableFormURL.indexOf("?") >= 0)
  536.         BindableFormURL = BindableFormURL.substring(0, BindableFormURL.indexOf("?"));
  537.     var CanonicalFormURL = g_objDispatch.GetCanonicalURL(BindableFormURL);
  538.     var FormName = CanonicalFormURL;
  539.     
  540.     var AttachmentsFieldName = "";
  541.     if (g_AttachmentsObject)
  542.         AttachmentsFieldName = g_AttachmentsObject.getAttribute("id");
  543.  
  544.     // here is where you put the call to pass the array fieldstringenum back to groove
  545.     if (g_IsSearch)
  546.         g_objDispatch.Search(FieldStringEnum);
  547.     else if (g_IsNewRecord)
  548.         g_objDispatch.AddRecord(FieldStringEnum, FormName, g_Record, FieldElementEnum, AttachmentsFieldName, g_AttachmentsElement);
  549.     else if (g_ModifyRecord)
  550.         g_objDispatch.ModifyRecord(FieldStringEnum, FormName, g_RecordID, FieldElementEnum, AttachmentsFieldName, g_AttachmentsElement);
  551.     else
  552.         g_objDispatch.SubmitData(FieldStringEnum, FormName, FieldElementEnum);
  553.  
  554.     if (!g_IsSearch && !g_CreateAnother)
  555.     {
  556.         g_objDispatch.LoadHomePage();
  557.         g_objDispatch.ShowUICommands(true);
  558.     }
  559.     else if (g_CreateAnother)
  560.     {
  561.         var strHref = location.href;
  562.         strHref = strHref.replace(/(.*)\?.*$/, "$1");
  563.         if (g_SelectedID != null)
  564.             strHref = strHref + "?SelectedID=" + g_SelectedID;
  565.         else
  566.         {
  567.             // Check to see if it is a response record, if the current record is not new.
  568.             var strFormType = document.body.getAttribute("FormType");
  569.             if (strFormType != null && strFormType == "Response")
  570.             {
  571.                 // If it is a response, get the parent id and pass it along.
  572.                 if (g_Record != null && g_Record.HasField("_ParentID"))
  573.                 {
  574.                     var strParentID = g_Record.OpenFieldAsDouble("_ParentID");
  575.                     strHref += "?SelectedID=" + strParentID;
  576.                 }
  577.             }
  578.         }
  579.         window.location.href = strHref;
  580.     }
  581.     else
  582.         return true;
  583. }
  584.  
  585. // === saveAndCreateAnother() ================================
  586. // celled when user presses the save and create another button
  587. function saveAndCreateAnother()
  588. {
  589.     g_CreateAnother = true;
  590.     submitData();
  591. }
  592.  
  593. // === resetData() =========================
  594. // called when user presses the reset button
  595. function resetData()
  596. {
  597.     if (!g_IsPreviewLayout)
  598.         location.reload(true);
  599. }
  600.  
  601. // === cancelEdit()==========================
  602. // called when user presses the cancel button
  603. function cancelEdit()
  604. {
  605.     if (!g_IsPreviewLayout)
  606.     {
  607.         g_objDispatch.LoadHomePage();
  608.         g_objDispatch.ShowUICommands(true);
  609.     }
  610.  
  611. }
  612.  
  613. // === DoSearch() =======================================
  614. // called from within the search window to submit a query
  615. function DoSearch()
  616. {
  617.     g_IsSearch = true;
  618.     return submitData();
  619. }
  620.  
  621. // === getPlainText(object) ======================
  622. // retrieve the plain text from a rich text object
  623. function getPlainText(i_TextView)
  624. {
  625.     // prepare for direct TOM access
  626.     i_TextView.Freeze(true);
  627.     i_TextView.HideDecorations(true);
  628.  
  629.     // retrieve TOM document
  630.     var TextCache = i_TextView.TextCache;
  631.     var Document = TextCache.Document;
  632.  
  633.     // retrieve plain text
  634.     var Range = Document.Range(0, 1073741823); // see "tom" typelib for tomForward
  635.     var PlainText = Range.Text;
  636.  
  637.     // we're done accessing the TOM directly
  638.     i_TextView.HideDecorations(false);
  639.     TextCache.Synchronize(1);
  640.     i_TextView.Freeze(false);
  641.     
  642.     // we're done!
  643.     return PlainText;
  644. }
  645.  
  646. // === addDocument() ============================================
  647. // adds document to HTMLComponentBridge for object initialization
  648. function addDocument()
  649. {
  650.     if (!g_IsPreviewLayout)
  651.         g_AttachmentsElement = g_objDispatch.AddHTMLDocument(document, g_Record);
  652. }
  653.  
  654. // === removeDocument() ===========================================
  655. // removes document from HTMLComponentBridge for object termination
  656. function removeDocument()
  657. {
  658.     if (!g_IsPreviewLayout)
  659.         g_objDispatch.RemoveHTMLDocument(document);
  660. }
  661.  
  662. // === addNewOption(object) ==============
  663. // add a custom option to a drop-down list
  664. function addNewOption(i_objSelect)
  665. {
  666.     var intSelected = i_objSelect.selectedIndex;
  667.     if (i_objSelect.options[intSelected].value == "GrooveAddOption")
  668.     {
  669.         window.setTimeout("int_addNewOption('" + i_objSelect.name + "')", 10);
  670.     }
  671. }
  672.  
  673. // === int_addNewOption(string) ============================================
  674. // had to create internal call so object was not held in case of form reload
  675. function int_addNewOption(i_strSelect)
  676. {
  677.     try
  678.     {
  679.         var strOption = g_objDispatch.AddOptionDialog("Enter the label for the new option:");
  680.         var objSelect = eval("getDocumentForm()." + i_strSelect);
  681.         if (strOption != null && strOption != "")
  682.             insertNewOption(objSelect, strOption);
  683.         else
  684.             objSelect.selectedIndex = 0;
  685.     }
  686.     catch (error)
  687.     {
  688.         var objError = new Error("There was an error adding the custom option to the drop-down list, most likely caused by the form reloading in response to a design change. Please try adding the custom option again.");
  689.         g_objDispatch.DisplayError(objError);
  690.     }
  691. }
  692.  
  693. // === insertNewOption(object, string) =========================
  694. // utility function to insert a new option into a select element
  695. function insertNewOption(i_objElement, i_strOption)
  696. {
  697.     var objOptions = i_objElement.options;
  698.     // Remove the "Custom..." option so the new one can be added at the end.
  699.     if (objOptions.length > 1)
  700.     {
  701.         if (!g_IsSearch && objOptions[0].text == "" && objOptions[0].value == "")
  702.             objOptions.remove(0);
  703.         if (objOptions[objOptions.length - 1].value == "GrooveAddOption")
  704.             objOptions.remove(objOptions.length - 1);
  705.     }
  706.     else if (objOptions.length == 1)
  707.     {
  708.         if (objOptions[0].value == "GrooveAddOption")
  709.             objOptions.remove(0);
  710.     }
  711.     // Add the new option with the string input by the user.
  712.     objOptions[objOptions.length] = new Option(i_strOption, i_strOption)
  713.     // Add the "Custom..." option back in at the end of the list.
  714.     objOptions[objOptions.length] = new Option("Custom...", "GrooveAddOption")
  715.     // Select the new option in the list.
  716.     i_objElement.selectedIndex = objOptions.length - 2;
  717. }
  718.  
  719. // === addCustomOptionToElement(object) ===================
  720. // add the "Custom..." option to the end of a SELECT object
  721. function addCustomOptionToElement(i_objElement)
  722. {
  723.     var objOptions = i_objElement.options;
  724.     if (objOptions.length > 0)
  725.     {
  726.         if (objOptions[objOptions.length - 1].value != "GrooveAddOption")
  727.             objOptions[objOptions.length] = new Option("Custom...", "GrooveAddOption");
  728.     }
  729.     else
  730.     {
  731.         // Add a blank option so that a new on can be added.
  732.         objOptions[objOptions.length] = new Option("", "");
  733.         objOptions[objOptions.length] = new Option("Custom...", "GrooveAddOption");
  734.     }
  735. }
  736.  
  737. // === addEvent(object, string, string) ===========
  738. // utility function to add code to an objects event
  739. function addEvent(i_objInput, i_strEvent, i_strScript)
  740. {
  741.     var strEvent = i_objInput.getAttribute(i_strEvent);
  742.     if (strEvent == null)
  743.         i_objInput.setAttribute(i_strEvent, "");
  744.  
  745.     // Clean up passed in script in case it is messed up.
  746.     i_strScript = i_strScript.replace(/^( )*/, "");
  747.     i_strScript = i_strScript.replace(/( )*$/, "");
  748.     if (i_strScript.charAt(i_strScript.length - 1) != ";" && i_strScript.charAt(i_strScript.length - 1) != "}")
  749.         i_strScript = i_strScript + ";";
  750.  
  751.     // If the event exists add to the current script, otherwise just add the new script.
  752.     if (strEvent != null && strEvent != "")
  753.     {
  754.         var regEvent = new RegExp("\{\n(.*)\n\}", "i");
  755.         var arrEvent = regEvent.exec(strEvent);
  756.         var strScript = RegExp.$1;
  757.         var strFunction = i_strScript + " " + strScript;
  758.     }
  759.     else
  760.         var strFunction = i_strScript;
  761.  
  762.     // Add the script to the object as an anonymous function.
  763.     eval("i_objInput." + i_strEvent + " = new Function(strFunction);");
  764. }
  765.  
  766. // === eventHandlers =============================
  767. // these functions handle events for form elements
  768. function onBlurHandler()
  769. {
  770.     eventHandler("OnBlur");
  771. }
  772.  
  773. function onFocusHandler()
  774. {
  775.     eventHandler("OnFocus");
  776. }
  777.  
  778. function onClickHandler()
  779. {
  780.     eventHandler("OnClick");
  781. }
  782.  
  783. function onChangeHandler()
  784. {
  785.     eventHandler("OnChange");
  786. }
  787.  
  788. function eventHandler(i_strEvent)
  789. {
  790.     try
  791.     {
  792.         var objElement = event.srcElement;
  793.         if (eval("typeof " + objElement.name + "_" + i_strEvent) != "undefined")
  794.             eval(objElement.name + "_" + i_strEvent + "(objElement)");
  795.     }
  796.     catch (error) {}
  797. }
  798.  
  799. // ========================================================================
  800. // ===                 initFormPage break-out functions                 ===
  801. // ========================================================================
  802.  
  803. // === initFormWithRecord(object, boolean) ================
  804. // initialize the form with the values stored in the record
  805. function initFormWithRecord(i_Record, i_IsNew)
  806. {
  807.     var DocumentForm = getDocumentForm();
  808.  
  809.     if (typeof i_Record == "undefined" || i_Record == null)
  810.     {
  811.         if (g_IsPreviewLayout)
  812.             return;
  813.         else if (g_IsPreviewPane)
  814.         {
  815.             g_objDispatch.OKMessageBox("The record you have selected to preview has been deleted.", "Record Deleted");
  816.             var strBasePath = g_objDispatch.GetBasePath();
  817.             window.location.href = strBasePath + "FormsBlankPage.html";
  818.         }
  819.         else
  820.         {
  821.             g_objDispatch.OKMessageBox("The record you have selected to edit has been deleted. You will be returned to the view.", "Record Deleted");
  822.             g_objDispatch.LoadHomePage();
  823.         }
  824.         return;
  825.     }
  826.  
  827.     if (!g_IsPreviewPane && !g_IsNewRecord)
  828.     {
  829.         // Mark the current record as read since it has been opened.
  830.         g_objDispatch.MarkRecordRead(true);
  831.  
  832.         // Update submit and reset button labels for a current record.
  833.         DocumentForm.SubmitButton.value = "Update";
  834.         DocumentForm.SubmitButton.title = "Save this updated record and show the data view";
  835.         DocumentForm.ResetButton.value = "Revert";
  836.         DocumentForm.ResetButton.title = "Revert to the previously saved field values for this record";
  837.         DocumentForm.CancelButton.title = "Close this record without saving any updates";
  838.     }
  839.  
  840.     // Display values of system fields on form.
  841.     initSystemFields(false);
  842.  
  843.     if (!i_IsNew)
  844.     {
  845.         // Load the data from the name value enum into the form.
  846.         var NameValueEnum = i_Record.OpenFieldNameValueEnum();
  847.         loadFormDataFromEnum(NameValueEnum);
  848.     }
  849.  
  850.     if (g_NoEdit)
  851.     {
  852.         DocumentForm.SubmitButton.style.display = "none";
  853.         DocumentForm.ResetButton.style.display = "none";
  854.  
  855.         for (var i = 0; i < DocumentForm.length; i++)
  856.         {
  857.             if (DocumentForm.elements[i].getAttribute("NAME") != "CancelButton" && DocumentForm.elements[i].getAttribute("NAME") != "PrintButton")
  858.                 DocumentForm.elements[i].disabled = true;
  859.         }
  860.     }
  861.  
  862.     // Make the attachments object read only if it is in the preview pane.
  863.     if (g_AttachmentsObject)
  864.     {
  865.         if (g_IsPreviewPane)
  866.             window.setTimeout("enableDocumentShare(true)", 10);
  867.         else
  868.             window.setTimeout("enableDocumentShare(false)", 10);
  869.     }
  870.  
  871.     g_ModifyRecord = true;
  872. }
  873.  
  874. // === disableFormElements(boolean) ===================
  875. // disable the form elements if they are supposed to be
  876. function disableFormElements(i_Disabled)
  877. {
  878.     var DocumentForm = getDocumentForm();
  879.  
  880.     for (var i = 0; i < DocumentForm.length; i++)
  881.     {
  882.         var DocumentElement = DocumentForm.elements[i];
  883.  
  884.         // Disable the element if it is supposed to be.
  885.         if (!g_ElementsEnabled)
  886.             DocumentElement.disabled = i_Disabled;
  887.  
  888.         // Blank out combo-box so that the default value is not always selected.
  889.         if (i_Disabled && !g_IsNewRecord && (DocumentElement.type == "select-one" || DocumentElement.type == "select-multiple"))
  890.         {
  891.             for (var j = 0; j < DocumentElement.options.length; j++)
  892.             {
  893.                 DocumentElement.options[j].selected = false;
  894.             }
  895.         }
  896.     }
  897.  
  898.     for (var i = 0; i < g_arrRichText.length; i++)
  899.     {
  900.         // Set the rich text fields to read only if they are supposed to be.
  901.         if (!g_ElementsEnabled)
  902.             g_arrRichText[i].ReadOnly = i_Disabled;
  903.     }
  904. }
  905.  
  906. // === loadFormDataFromEnum(object) =================
  907. // load the data from a name/value enum into the form
  908. function loadFormDataFromEnum(i_NameValueEnum)
  909. {
  910.     var DocumentForm = getDocumentForm();
  911.     var arrDates = document.getElementsByName("groove_date");
  912.  
  913.     while (i_NameValueEnum.HasMore())
  914.     {
  915.         var NameValuePair = i_NameValueEnum.OpenNextPair();
  916.         var strName = NameValuePair.First;
  917.         var strValue = NameValuePair.Second;
  918.  
  919.         // Don't pass system field through as they are not used.
  920.         // System field names begin with an underscore and a capital letter (i.e. "_Created").
  921.         if (strName.search(/^_[A-Z]/) == 0)
  922.             continue;
  923.  
  924.         var arrElements = document.getElementsByName(strName);
  925.         for (var i = 0; i < arrDates.length; i++)
  926.         {
  927.             var strParentName = arrDates[i].parentElement.getAttribute("NAME");
  928.             if (strParentName != null && strParentName == strName)
  929.             {
  930.                 arrElements = new Array(arrDates[i]);
  931.                 break;
  932.             }
  933.         }
  934.  
  935.         for (var i = 0; i < arrElements.length; i++)
  936.         {
  937.             var DocumentElement = arrElements[i];
  938.             var ElementType = DocumentElement.type;
  939.  
  940.             if (ElementType == "text" || ElementType == "password" || ElementType == "textarea")
  941.             {
  942.                 var strDataType = DocumentElement.getAttribute("DataType");
  943.                 if (strDataType != null && strDataType == "Date")
  944.                 {
  945.                     if (strValue != 0)
  946.                     {
  947.                         var intDateFormat = g_objDispatch.GrooveIntlDateFormatStyle_Short;
  948.                         var strDateFormat = DocumentElement.parentElement.getAttribute("FormatDateShortFormat");
  949.                         if (strDateFormat == null || strDateFormat == "")
  950.                         {
  951.                             strDateFormat = DocumentElement.parentElement.getAttribute("FormatDateLongFormat");
  952.                             intDateFormat = g_objDispatch.GrooveIntlDateFormatStyle_Full;
  953.                         }
  954.  
  955.                         DocumentElement.value = g_objDispatch.LocalFormatDate(parseInt(strValue), strDateFormat, intDateFormat);
  956.                     }
  957.                     else
  958.                         DocumentElement.value = "";
  959.                 }
  960.                 else if (strDataType != null && strDataType == "Numeric")
  961.                 {
  962.                     DocumentElement.value = strValue;
  963.                     formatNumericFromDouble(DocumentElement);
  964.                 }
  965.                 else
  966.                     DocumentElement.value = strValue;
  967.  
  968.                 // Fire the onblur event to format the value.
  969.                 if (g_ElementsEnabled || g_IsPreviewPane)
  970.                     DocumentElement.fireEvent("onblur");
  971.             }
  972.             else if (ElementType == "checkbox")
  973.             {
  974.                 if (strValue != "")
  975.                     DocumentElement.checked = true;
  976.                 else
  977.                     DocumentElement.checked = false;
  978.             }
  979.             else if (ElementType == "radio" && DocumentElement.value == strValue)
  980.             {
  981.                 DocumentElement.checked = true;
  982.             }
  983.             else if (ElementType == "select-one")
  984.             {
  985.                 var blnOptionFound = false;
  986.                 for (var j = 0; j < DocumentElement.options.length; j++)
  987.                 {
  988.                     if (DocumentElement.options[j].value == strValue)
  989.                     {
  990.                         DocumentElement.options[j].selected = true;
  991.                         blnOptionFound = true;
  992.                     }
  993.                 }
  994.  
  995.                 var strCustom = DocumentElement.getAttribute("CUSTOM");
  996.                 if (!blnOptionFound && strCustom != null && strCustom != "")
  997.                     insertNewOption(DocumentElement, strValue);
  998.             }
  999.             else if (ElementType == "select-multiple")
  1000.             {
  1001.                 var MultipleArray = strValue.split(",");
  1002.                 for (var j = 0; j < MultipleArray.length; j++)
  1003.                 {
  1004.                     for (var h = 0; h < DocumentElement.options.length; h++)
  1005.                     {
  1006.                         if (MultipleArray[j] == DocumentElement.options[h].value || (MultipleArray[j] == DocumentElement.options[h].text && DocumentElement.options[h].value == ""))
  1007.                             DocumentElement.options[h].selected = true;
  1008.                     }
  1009.                 }
  1010.             }
  1011.         }
  1012.     }
  1013.  
  1014.     window.setTimeout("enableTextView()", 250);
  1015. }
  1016.  
  1017. // === enableTextView() ========================
  1018. // Fills in the data for the RTF fields
  1019. function enableTextView()
  1020. {
  1021.     for (var i = 0; i < g_arrRichText.length; i++)
  1022.     {
  1023.         // Preview the values for rich text objects on the page.
  1024.         var strName = g_arrRichText[i].getAttribute("Name");
  1025.         if (strName != null && g_Record.HasField(strName))
  1026.         {
  1027.             var RTFElement = g_Record.OpenFieldAsElement(strName);
  1028.             var RichTextObjectName = null;
  1029.             try
  1030.             {
  1031.                 RichTextObjectName = g_arrRichText[i].IGrooveComponent.OpenName();
  1032.             }
  1033.             catch (error)
  1034.             {
  1035.             }
  1036.             
  1037.             if (RichTextObjectName != null && RichTextObjectName != "")
  1038.                 g_arrRichText[i].CellContent.ReadContentFromElement(RTFElement);
  1039.             else
  1040.                 window.setTimeout("enableTextView()", 100);
  1041.         }
  1042.     }
  1043. }
  1044.  
  1045. // === enableDocumentShare() ========================
  1046. // set the read only mode for the document share view
  1047. function enableDocumentShare(i_ReadOnly)
  1048. {
  1049.     try
  1050.     {
  1051.         if (g_AttachmentsObject.Properties2.Initialized)
  1052.         {
  1053.             g_AttachmentsObject.Properties2.SetReadOnlyMode(i_ReadOnly);
  1054.             if (!i_ReadOnly)
  1055.                 g_AttachmentsObject.Properties.SetIsDragDropTarget(true);
  1056.         }
  1057.         else
  1058.             window.setTimeout("enableDocumentShare(" + i_ReadOnly + ")", 10);
  1059.     }
  1060.     catch (error)
  1061.     {
  1062.         window.setTimeout("enableDocumentShare(" + i_ReadOnly + ")", 10);
  1063.     }
  1064. }
  1065.  
  1066. // === cleanUpFormElements() ======================================
  1067. // clean up and repair form elements before submitting data to them
  1068. function cleanUpFormElements()
  1069. {
  1070.     // Replace all instances of "'" with "'" in the form.
  1071.     if (document.body.hasChildNodes())
  1072.     {
  1073.         var objChildren = document.body.childNodes;
  1074.         for (var i = 0; i < objChildren.length; i++)
  1075.         {
  1076.             var objChild = objChildren.item(i);
  1077.             if (objChild.outerHTML != null)
  1078.             {
  1079.                 // Replace apostrophes at the beginning of the line.
  1080.                 if (objChild.outerHTML.search(/^&apos;/) >= 0)
  1081.                     objChild.outerHTML = objChild.outerHTML.replace(/^&apos;/g, "'");
  1082.                 // Replace apostrophes that are not in attribute values.
  1083.                 if (objChild.outerHTML.search(/([^=])&apos;/) >= 0)
  1084.                     objChild.outerHTML = objChild.outerHTML.replace(/([^=])&apos;/g, "$1'");
  1085.             }
  1086.         }
  1087.     }
  1088.  
  1089.     var DocumentForm = getDocumentForm();
  1090.     for (var i = 0; i < DocumentForm.length; i++)
  1091.     {
  1092.         var DocumentElement = DocumentForm.elements[i];
  1093.  
  1094.         // Set the initial value for a date field if is valid.
  1095.         if (DocumentElement.getAttribute("DataType") == "Date")
  1096.         {
  1097.             var InitialValue = DocumentElement.parentElement.getAttribute("VALUE");
  1098.             if (InitialValue != null)
  1099.             {
  1100.                 // If the initial value should be today get the date string for today.
  1101.                 if (InitialValue == "[today]")
  1102.                 {
  1103.                     var strDataType = DocumentElement.getAttribute("DataType");
  1104.                     if (strDataType != null && strDataType == "Date")
  1105.                     {
  1106.                         var intDateFormat = g_objDispatch.GrooveIntlDateFormatStyle_Short;
  1107.                         var strDateFormat = DocumentElement.parentElement.getAttribute("FormatDateShortFormat");
  1108.                         if (strDateFormat == null || strDateFormat == "")
  1109.                         {
  1110.                             strDateFormat = DocumentElement.parentElement.getAttribute("FormatDateLongFormat");
  1111.                             intDateFormat = g_objDispatch.GrooveIntlDateFormatStyle_Full;
  1112.                         }
  1113.                         InitialValue = g_objDispatch.LocalFormatDate(new Date().valueOf(), strDateFormat, intDateFormat);
  1114.                     }
  1115.                     else
  1116.                         InitialValue = new Date().toDateString();
  1117.                 }
  1118.                 DocumentElement.value = InitialValue;
  1119.                 formatDate(DocumentElement);
  1120.             }
  1121.         }
  1122.  
  1123.         // Replace all instances of ' with an apostrophe in the form's element values.
  1124.         if (DocumentElement.tagName == "SELECT")
  1125.         {
  1126.             for (var j = 0; j < DocumentElement.options.length; j++)
  1127.             {
  1128.                 var DocumentOption = DocumentElement.options[j];
  1129.                 if (DocumentOption.value.search(/'/) >= 0)
  1130.                     DocumentOption.value = DocumentOption.value.replace(/'/g, "'");
  1131.             }
  1132.         }
  1133.         else if (DocumentElement.value != null && DocumentElement.value != "")
  1134.         {
  1135.             if (DocumentElement.value.search(/'/) >= 0)
  1136.                 DocumentElement.value = DocumentElement.value.replace(/'/g, "'");
  1137.         }
  1138.  
  1139.         // Add event handler function call to each element so it can be used by developers.
  1140.         if (DocumentElement.name != "")
  1141.         {
  1142.             DocumentElement.attachEvent('onblur', onBlurHandler);
  1143.             DocumentElement.attachEvent('onfocus', onFocusHandler);
  1144.             DocumentElement.attachEvent('onclick', onClickHandler);
  1145.             // OnChange is only supported by SELECT, TEXTAREA, and text INPUT.
  1146.             if (DocumentElement.tagName == "SELECT" || DocumentElement.tagName == "TEXTAREA" || (DocumentElement.tagName == "INPUT" && DocumentElement.type == "text"))
  1147.                 DocumentElement.attachEvent('onchange', onChangeHandler);
  1148.         }
  1149.     }
  1150.  
  1151.     // Fix the default text of any textarea fields in the page.
  1152.     var arrTextArea = document.getElementsByTagName("TEXTAREA");
  1153.     for (var i = 0; i < arrTextArea.length; i++)
  1154.     {
  1155.         arrTextArea[i].value = arrTextArea[i].value.replace(/^[ \n\r]*/, "");
  1156.         arrTextArea[i].value = arrTextArea[i].value.replace(/[ \n\r]*$/, "");
  1157.     }
  1158.  
  1159.     try
  1160.     {
  1161.         // Get an array of groove objects (usually rich text) on the page.
  1162.         var arrObject = document.getElementsByTagName("OBJECT");
  1163.         for (var i = 0; i < arrObject.length; i++)
  1164.         {
  1165.             var strDataType = arrObject[i].getAttribute("DataType");
  1166.             if (strDataType != null && strDataType == "RichText")
  1167.             {
  1168.                 var strDefault = arrObject[i].getAttribute("DEFAULT");
  1169.                 if (strDefault != null)
  1170.                     arrObject[i].RTFContent = strDefault;
  1171.  
  1172.                 var strReadOnly = arrObject[i].getAttribute("READONLY");
  1173.                 if (strReadOnly != null && strReadOnly != "true")
  1174.                     g_arrRichText[g_arrRichText.length] = arrObject[i];
  1175.                 else
  1176.                     arrObject[i].ReadOnly = true;
  1177.             }
  1178.             else if (arrObject[i].getAttribute("DataType") == "Attachments")
  1179.                 g_AttachmentsObject = arrObject[i];
  1180.         }
  1181.     }
  1182.     catch (error)
  1183.     {
  1184.         g_objDispatch.ActiveXMessageBox();
  1185.         return;
  1186.     }
  1187.  
  1188.  
  1189.     // Get an array of drop-down list boxes on the page.
  1190.     var arrSelect = document.getElementsByTagName("SELECT");
  1191.     for (var i = 0; i < arrSelect.length; i++)
  1192.     {
  1193.         if (arrSelect[i].getAttribute("Members") != null && arrSelect[i].getAttribute("Members") == "true")
  1194.         {
  1195.             var MemberNameArray = g_objDispatch.GetMemberNameArray();
  1196.             
  1197.             for (var j = 0; j < MemberNameArray.length; j++)
  1198.             {
  1199.                 arrSelect[i].options[arrSelect[i].options.length] = new Option(MemberNameArray[j], MemberNameArray[j]);
  1200.             }
  1201.         }
  1202.     }
  1203.  
  1204.     // Make any fields invisible that need to be.
  1205.     var arrDiv = document.getElementsByTagName("TR");
  1206.     for (var i = 0; i < arrDiv.length; i++)
  1207.     {
  1208.         var strInvisible = arrDiv[i].getAttribute("INVISIBLE");
  1209.         if (strInvisible != null && strInvisible != "")
  1210.             arrDiv[i].style.display = "none";
  1211.     }
  1212.  
  1213.     // Fix the onclick events for any script buttons.
  1214.     var arrButton = document.getElementsByTagName("BUTTON");
  1215.     for (var i = 0; i < arrButton.length; i++)
  1216.     {
  1217.         var strOnClickEvent = arrButton[i].getAttribute("ONCLICKEVENT");
  1218.         if (strOnClickEvent != null && strOnClickEvent != "")
  1219.         {
  1220.             strOnClickEvent = strOnClickEvent.replace(/'/g, "'");
  1221.             strOnClickEvent = strOnClickEvent.replace(/"/g, "\"");
  1222.             addEvent(arrButton[i], "onclick", strOnClickEvent);
  1223.         }
  1224.     }
  1225. }
  1226.  
  1227. // === getQueryStringVariables() ======================
  1228. // get global variable values from document querystring
  1229. function getQueryStringVariables()
  1230. {
  1231.     var QueryString = String(window.location.search).substring(1);
  1232.     var SearchArray = QueryString.split("&");
  1233.     for (var i = 0; i < SearchArray.length; i++)
  1234.     {
  1235.         var Request = SearchArray[i].split("=")[0];
  1236.         if (Request == "RecordID")
  1237.             g_RecordID = SearchArray[i].split("=")[1];
  1238.         else if (Request == "SelectedID")
  1239.         {
  1240.             g_SelectedID = SearchArray[i].split("=")[1];
  1241.             var strFormType = document.body.getAttribute("FormType");
  1242.             if (strFormType != null && strFormType == "Response")
  1243.                 g_IsResponse = true;
  1244.         }
  1245.         else if (Request.indexOf("preview") >= 0 || Request.indexOf("previewlayout") >= 0 || Request.indexOf("layout") >= 0 || Request.indexOf("search") >= 0)
  1246.         {
  1247.             if (Request == "preview")
  1248.                 g_IsPreviewPane = true;
  1249.             else if (Request == "layout")
  1250.                 g_IsLayout = true;
  1251.             else if (Request == "search")
  1252.                 g_IsSearch = true;
  1253.  
  1254.             // Set the elements enabled variable for preview, preview layout, and layout.
  1255.             if (Request == "preview" || Request == "previewlayout" || Request == "layout")
  1256.                 g_ElementsEnabled = false;
  1257.  
  1258.             // Set variable for preview, layout, and search.
  1259.             if (Request == "previewlayout" || Request == "layout" || Request == "search")
  1260.                 g_IsPreviewLayout = true;
  1261.         }
  1262.         else if (Request.indexOf("noedit") >= 0)
  1263.         {
  1264.             g_NoEdit = true;
  1265.         }
  1266.     }
  1267. }
  1268.  
  1269. // === createNewRecord() =======================
  1270. // create a new record to save the new data into
  1271. function createNewRecord()
  1272. {
  1273.     var NewRecord = g_objDispatch.CreateNewRecord();
  1274.     if (typeof NewRecord != "undefined" && NewRecord != null)
  1275.     {
  1276.         g_Record = NewRecord;
  1277.         g_RecordID = g_Record.RecordID;
  1278.         g_IsNewRecord = true;
  1279.         g_objDispatch.GrooveDebugFunctions.OutputString("\nNew Record created.  RecordID: " + g_RecordID + "\n\n");
  1280.     }
  1281. }
  1282.  
  1283. // === clearAllFormValues(boolean) ====================================
  1284. // clear all values from the form, add a blank to SELECT tags if needed
  1285. function clearAllFormValues(i_blnBlank)
  1286. {
  1287.     var DocumentForm = getDocumentForm();
  1288.  
  1289.     for (var i = 0; i < DocumentForm.length; i++)
  1290.     {
  1291.         var DocumentElement = DocumentForm.elements[i];
  1292.         if (DocumentElement.type == "text" || DocumentElement.type == "password" || DocumentElement.type == "textarea")
  1293.             DocumentElement.value = "";
  1294.         else if (DocumentElement.type == "checkbox")
  1295.             DocumentElement.checked = false;
  1296.         else if (DocumentElement.type == "radio")
  1297.             DocumentElement.checked = false;
  1298.         else if (DocumentElement.type == "select-one" || DocumentElement.type == "select-multiple")
  1299.         {
  1300.             for (var j = 0; j < DocumentElement.options.length; j++)
  1301.             {
  1302.                 DocumentElement.options[j].selected = false;
  1303.             }
  1304.  
  1305.             // Add a blank option to the combo-box and select it.
  1306.             if (i_blnBlank)
  1307.             {
  1308.                 var objOption = document.createElement("OPTION");
  1309.                 DocumentElement.options.add(objOption, 0);
  1310.                 DocumentElement.options[0].selected = true;
  1311.             }
  1312.         }
  1313.     }
  1314.  
  1315.     for (var i = 0; i < g_arrRichText.length; i++)
  1316.     {
  1317.         g_arrRichText[i].RTFContent = "";
  1318.     }
  1319. }
  1320.  
  1321. // === setupSpecializedFields() =====================================
  1322. // set-up some specialized fields and set focus to first form element
  1323. function setupSpecializedFields()
  1324. {
  1325.     var DocumentForm = getDocumentForm();
  1326.  
  1327.     var blnFocusSet = false;
  1328.     for (var i = 0; i < DocumentForm.length; i++)
  1329.     {
  1330.         var DocumentElement = DocumentForm.elements[i];
  1331.  
  1332.         // Set the focus to be the first non-disabled, visible form element.
  1333.         if (!blnFocusSet && !DocumentElement.disabled && DocumentElement.getAttribute("INVISIBLE") != "true" && DocumentElement.parentElement.getAttribute("INVISIBLE") != "true")
  1334.         {
  1335.             DocumentElement.focus();
  1336.             blnFocusSet = true;
  1337.         }
  1338.  
  1339.         // Add the "Custom..." option to the end of the list for combo boxes.
  1340.         var strCustom = DocumentElement.getAttribute("CUSTOM");
  1341.         if (DocumentElement.tagName == "SELECT" && strCustom != null && strCustom != "")
  1342.             addCustomOptionToElement(DocumentElement);
  1343.  
  1344.         // Add the red asterisk the signifys the field is required.
  1345.         addRequiredAsterisk(DocumentElement);
  1346.     }
  1347.  
  1348.     var arrSpan = document.getElementsByTagName("SPAN");
  1349.     for (var i = 0; i < arrSpan.length; i++)
  1350.     {
  1351.         if (arrSpan[i].className == "Radio")
  1352.             addRequiredAsterisk(arrSpan[i]);
  1353.     }
  1354. }
  1355.  
  1356. // === addRequiredAsterisk(object) ========================
  1357. // add the red asterisk the signifies the field is required
  1358. function addRequiredAsterisk(i_objElement)
  1359. {
  1360.     if (g_ElementsEnabled && !g_IsSearch)
  1361.     {
  1362.         // Add a red asterisk after required fields.
  1363.         if (i_objElement.getAttribute("VldtRequired") != null && i_objElement.getAttribute("VldtRequired") != "")
  1364.             i_objElement.insertAdjacentHTML("afterEnd", " <font style=\"color:red\">*</font>");
  1365.         else if (i_objElement.parentElement.getAttribute("VldtRequired") != null && i_objElement.parentElement.getAttribute("VldtRequired") != "" && i_objElement.tagName == "BUTTON")
  1366.             i_objElement.insertAdjacentHTML("afterEnd", " <font style=\"color:red\">*</font>");
  1367.     }
  1368. }
  1369.  
  1370. // === designChanged() ===================================
  1371. // called when design has changed, disable useless buttons
  1372. function designChanged()
  1373. {
  1374.     if (!g_Initialized)
  1375.         window.setTimeout("designChanged()", 250);
  1376.     if (!g_HasDesignChanged)
  1377.     {
  1378.         var DocumentForm = getDocumentForm();
  1379.         // Disable the "Save" and "Save and Create Another" buttons.
  1380.         DocumentForm.SubmitButton.title += " (disabled by design change)";
  1381.         DocumentForm.SubmitButton.disabled = true;
  1382.         DocumentForm.ApplyButton.title += " (disabled by design change)";
  1383.         DocumentForm.ApplyButton.disabled = true;
  1384.         // Disable the reset button if the form no longer exists.
  1385.         var FormID = g_objDispatch.RightBack(location.pathname, "/");
  1386.         if (!g_objDispatch.VerifyFormExistsForURL(FormID))
  1387.         {
  1388.             DocumentForm.ResetButton.title += " (disabled by design change, this form has been deleted)";
  1389.             DocumentForm.ResetButton.disabled = true;
  1390.         }
  1391.         // Disable the attachments buttons if they are present
  1392.         if (g_AttachmentsObject)
  1393.         {
  1394.             removeDocument();
  1395.             for (var i = 0; i < DocumentForm.length; i++)
  1396.             {
  1397.                 var DocumentElement = DocumentForm.elements[i];
  1398.                 if (DocumentElement.tagName == "BUTTON" && DocumentElement.parentNode.className == "AttachmentsField")
  1399.                     DocumentElement.disabled = true;
  1400.                 
  1401.             }
  1402.             
  1403.             addDocument();
  1404.             if (g_AttachmentsObject.Properties2.Initialized)
  1405.                 g_AttachmentsObject.Properties2.SetReadOnlyMode(true);
  1406.         }
  1407.         
  1408.  
  1409.         g_HasDesignChanged = true;
  1410.     }
  1411. }
  1412.  
  1413. // === roleChanged() ===================================
  1414. // called when role has changed, disable/enable buttons appropriate to change
  1415. function roleChanged()
  1416. {
  1417.     var EnableButtons = false;
  1418.     if (g_IsNewRecord)
  1419.         EnableButtons = g_objDispatch.CanCreate();
  1420.     else
  1421.         EnableButtons = g_objDispatch.CanEdit(g_RecordID);    
  1422.  
  1423.     var DocumentForm = getDocumentForm();
  1424.     // Enable or Disable the "Save" and "Save and Create Another" buttons.
  1425.     if (!EnableButtons)
  1426.     {
  1427.         if (DocumentForm.SubmitButton.title.indexOf(" (disabled by role change)") < 0)
  1428.         {
  1429.             DocumentForm.SubmitButton.title += " (disabled by role change)";
  1430.             DocumentForm.ApplyButton.title += " (disabled by role change)";
  1431.         }
  1432.     }
  1433.     else
  1434.     {
  1435.         DocumentForm.SubmitButton.title = DocumentForm.SubmitButton.title.replace(/ \(disabled by role change\)/, "");
  1436.         DocumentForm.ApplyButton.title = DocumentForm.ApplyButton.title.replace(/ \(disabled by role change\)/, "");
  1437.     }
  1438.     DocumentForm.SubmitButton.disabled = !EnableButtons;
  1439.     DocumentForm.ApplyButton.disabled = !EnableButtons;
  1440.     
  1441.     // Disable the attachments buttons if they are present
  1442.     if (g_AttachmentsObject)
  1443.     {
  1444.         removeDocument();
  1445.         for (var i = 0; i < DocumentForm.length; i++)
  1446.         {
  1447.             var DocumentElement = DocumentForm.elements[i];
  1448.             if (DocumentElement.tagName == "BUTTON" && DocumentElement.parentNode.className == "AttachmentsField")
  1449.                 DocumentElement.disabled = !EnableButtons;
  1450.             
  1451.         }
  1452.         
  1453.         addDocument();
  1454.         if (g_AttachmentsObject.Properties2.Initialized)
  1455.             g_AttachmentsObject.Properties2.SetReadOnlyMode(!EnableButtons);
  1456.     }
  1457.  
  1458.  
  1459.     
  1460. }
  1461.  
  1462. // === printForm() ============================
  1463. // print the data that is currently on the form
  1464. function printForm()
  1465. {
  1466.     window.print();
  1467. }
  1468.  
  1469. // === getDocumentForm() =============
  1470. // return the form object that is used
  1471. function getDocumentForm()
  1472. {
  1473.     return document.GrooveFormBase;
  1474. }
  1475.  
  1476. // === getScriptDispatch() ===============================
  1477. // safely get the script dispatch from the forms glue code
  1478. function getScriptDispatch()
  1479. {
  1480.     try
  1481.     {
  1482.         var objDispatch = window.external.Delegate.GetScriptDispatch();
  1483.         return objDispatch;
  1484.     }
  1485.     catch (error)
  1486.     {
  1487.         alert("This web page should only be opened from within Groove. Please close the window.");
  1488.         return null;
  1489.     }
  1490. }