Other


Validate Field By Pattern

Description:

This function will enforce a regex pattern on the specified field and will set the field to invalid if it does not match.

The capability to use patterns and regular expressions for validating Single Line fields can be set through the field's advanced property settings.

Usage Notes:

For example, you may want to validate a single line field as a US based phone number. In the onItemChange event of the field you would place:

app.getSharedData().validateByPattern(BOA, /^\(\d{3}\) \d{3}-\d{4}$/, "The number provided does not meet the required format");

Function:

app.getSharedData().validateByPattern = function(theItem, pattern, errMsg) {
  var re = new RegExp(pattern);
  if(!re.test(theItem.getValue())) {
   theItem.setValid(false, errMsg);
  } else {
    theItem.setValid(true, "");
  }
}


Pad Field Value

Description:

This function can be used to pad a string with a padding character up to a specified length.

Usage Notes:

Place this function in the onLoad event of the form.  Then in the onItemChange event of the field you wish to pad place:

BOA.setValue(app.getSharedData.padValue(BOA.getValue(), "0", 4));

This will pad the value with zeros up to a total string length of 4.

Function:

// theVal - the string you want to pad
// padChar - the character you want to use to pad the string
// desiredLength - the total length the resulting string should be
app.getSharedData.padValue = function(theVal, padChar, desiredLength) {
  while(theVal.length < desiredLength) {
    theVal = padChar + theVal;              
  }
  return theVal;
}


Calculate Duration

Description:

This function can be used to calculate the duration between two times.  This function currently supports calculating the duration into hours and minutes.  You could further enhance this function to support months and years, but the output will always be rendered as a string representing the number of hours.

Usage Notes:

1. Copy the code to the Settings...Events...onStart section of your application.

2. To call the function, on the onItemChange of your date fields add:

  var dur = app.getSharedData().calcDuration(BO.F_Time.getValue(),
     BO.F_Time0.getValue(),true);
     BO.F_SingleLine.setValue(dur);

This approach takes just the time values, but you could create a different function that took the actual field objects and then you could add validation and error messages if your business case required it. 

For example, you could make sure the start time did not come after the end time.  You could also force either time to be within a specific window (i.e. 8-5).  By using the field objects as the parameters you could use the item.setValid() functions to set them invalid and show error text if the user entered an invalid value.

Function:

// startTime - Can be date, time or dateTime
// endTime - Can be date, time or dateTime
// rndHours - Round the result to the highest integer (hour). Values are true or false.
app.getSharedData().calcDuration = function(startTime, endTime, rndHours) {  

  //convert to milliseconds
  var d1 = startTime.getTime();
  var d2 = endTime.getTime();  
  var diff = d2 - d1;
  var durHours = diff / 1000 / 60 / 60;
  if(rndHours) {
    Math.ceil(durHours);
  }
  return durHours;
}


Calculate Sum of Fields

Description:

Returns the sum of all the fields specified

Usage:

Copy the function to Settings...Events section of your application.  Place this in the onShow event of the field where the sum is shown and then again in the onItemChange event of all the fields included in the summation:

BO.F_Sum.setValue(app.getSharedData().sumFields(BO, new Array("F_Field1", "F_Field2", "F_Field3", "F_Field4")));

This function assumes that the fields being provided are simple fields in your form, either String, Number or Currency. 

Example that uses the code -> Sum Multiple Fields Using JavaScript

The example demonstrates how to use the recursive function to dynamically add the summation to the onItemChange event of all the fields defined in the array.

Function:

// fields - array of field objects - new Array(BO.F_Field1, BO.F_Field2, ...)
app.getSharedData().sumFields = function(theBO, fields) {  
  var sum = 0;
  for(var i = 0; i < fields.length; i++) {
    var f = get(fields, i);
    var itm = get(theBO, f);
    var v = itm.getValue();
    if(typeof itm !== "undefined" && v !== "" && !isNaN(+v)) {  //!isNaN(+v) is specifically to omit text fields when their value is not numeric
        sum += parseFloat(v);
    }
  }
  return sum;
}


Check if Field takes an Input

Usage:

This function is useful for quickly determining if an item takes user input.  This function is commonly used in conjunction with the Recursive function (also on this page), where you may want to take some action for input items in your form in the onLoad event.  For example, when the form loads connect an event listener so that some code will be executed when the event is triggered.

1. Copy the function in to the Application onStart event

2. Execute the function by calling it in the desired event:

 - if you place this in the mouseover event of an item it will show an alert indicating if the item takes an input or not:

alert(app.getSharedData().isInputField(item.getType()));

- Perhaps you want to make a decision based on the result

if(app.getSharedData().isInputField(item.getType())) {
  //if true
} else {
  //if false
}

Function 

app.getSharedData().isInputField = function(theItemType) {
  var r = false;
 if(theItemType === "text" || theItemType === "textArea" || theItemType === "date" ||
     theItemType === "checkGroup" || theItemType === "checkBox" || theItemType === "radioGroup" || theItemType === "number" ||
     theItemType === "currency" || theItemType === "comboBox" || theItemType === "horizontalSlider" ||
     theItemType === "choiceSlider" || theItemType === "time" || theItemType === "webLink" ||
     theItemType === "surveyQuestion" || theItemType === "emailAddress" || theItemType === "password" || theItemType === "timeStamp") {
    r = true;
  }
  return r;
}


Multiply Fields

Usage:

Copy the function to Settings...Events section of your application.  Place this in the onShow event of the field where the sum is shown and then again in the onItemChange event of all the fields included in the summation:

BO.F_Result.setValue(app.getSharedData().multiplyFields(new Array(BO.F_Field1, BO.F_Field2, BO.F_Field3, BO.F_Field4)));

This function assumes that the fields being provided are simple fields in your form, either String, Number or Curency. 

Function:

app.getSharedData().multiplyFields = function(fields) {   
  var result = 1;
  for(var i = 0; i < fields.length; i++) {
    var f = get(fields, i);
      if(f.getValue() !== "") {
        result *= parseFloat(f.getValue());
      }
     }
  return result;
}


Invalidate Field Based on Length

Description:

Function that can be used to check the content of a field and set it to invalid if it exceeds a specified length.

Usage Notes:

- Place the function in the Settings...Events

- Use the function in the onLiveItemChange event of the field you want to validate and change parameters as desired:

app.getSharedData().fieldLengthValidation(item, 3, 'Field will only accept 3 characters or less');

Function:

// theItem - the UI object of the item to validate
// theLength - the max length of the field, if exceeded the field will be set to invalid
// theMsg - The text to render if the length is exceeded.
app.getSharedData().fieldLengthValidation = function (theItem, theLength, theMsg) {
  var dval = theItem.getDisplayValue();
  if(dval.length > theLength) {
    theItem.getBOAttr().setValid(false, theMsg);
  } else {
    theItem.getBOAttr().setValid(true, '');
  }
}


Recursive Function to Walk all Items in a Form

Description:

Note: This function was modified on Feb 28, 2015 to a new 2.0 version!  I learned something new and wanted to make sure I shared it.  This function was not as generic as it could have been.  I recently encountered a scenario where I wanted to walk all the items in a container and perform action A and then walk all the items in a different container and perform action B.  With the old function I would have to create two copies of the function and replace the content in the else labelled "//otherwise do something".  With the power of JavaScript we can actually make it even more generic!  I have created a third function as part of this group called processItem.

Usage Notes:

If you have a need to walk all the items in a form and then perform some operation on each one, you could use these functions.  Place the functions in the Settings...Events...Custom Actions.  Then you can call the main function app.getSharedData().getItem(page) and it will iterate through all the objects on that page, including all the items within a container (section, tabbed folder). 

Some examples of this function are:

Walk all the items in a form:

app.getSharedData().getItem(form, app.getSharedData().processItem)

Walk all the items in a page:

app.getSharedData().getItem(form.getPage('P_Page1'), app.getSharedData().processItem) //if you place in the form onLoad event you have to qualify the page

Walk all the items in a section:

app.getSharedData().getItem(item, app.getSharedData().processItem) //if you place this in the onShow event of the section

Walk all the items in a tabbedFolder:

app.getSharedData().getItem(form.getPage('P_Page1').F_TabbedFolder, app.getSharedData().processItem) //if you place this in the onLoad event of the form

If you wanted to only perform an operation on a specific item type then you could further modify the function:

if(item.getType() === "text") {
//do your thing
}

The item types are:

Item

Type

Item

Type

AttachmentattachmentPasswordpassword
ButtonbuttonSingle Line Entrytext
Check BoxcheckBoxSectionsection
Choice SliderchoiceSlider

CurrencycurrencySelect ManycheckGroup
datedateSelect OneradioGroup
Drop DowncomboBoxSurveysurvey
EmailemailAddressSurvey QuestionsurveyQuestion
Folder TabtabFolderTabTabbed FoldertabFolder
HTML FragmenthtmlAreaTableaggregationListContainer
ImageimageTextrichText
MediamediaTimetime
Multi-Line EntrytextAreaTime StamptimeStamp
NumbernumberWebsitewebLink
Numeric SliderhorizontalSlider

PagepageWeb LinkstaticWebLink
Page NavigationpageNavigator

Function:

app.getSharedData().processItem = function(item) {

  //do whatever you want to the item...
   alert(item.getId() + " : " + item.getValue());

  //set item to inactive
  if(app.getSharedData().isInputField(item.getType())) {
    item.setActive(false);
  }
 //if(item.getType() === "text") {
   //do your thing
 //}

}

/*
* Returns true if the current item has children, otherwise false.
*/
app.getSharedData().hasItems = function(containerID) {
   var list = containerID.getChildren();
   if(list.getLength() > 0) {
    return true;
    } else {
       return false;
    }   
}

/*
* Recursive function used for counting form items.
* containerID: UI item (i.e. page or item)
* processItem: the function that contains the work we want to perform on the item we have accessed
*/
app.getSharedData().getItem = function(containerID, processItem) {
     var itemList;
     var pageList;
     var pageCount = 1;
     debugger;
     
     //check to see if the container is a form as it requires different processing
     if(containerID.getType() === "form") {
          pageList = containerID.getPageIds(); //list of the page IDs - not the actual objects!!
         pageCount = pageList.length;
      } else {
      itemList = containerID.getChildren();    
    }

   //need a loop to account for different pages
   for(var p=0; p<pageCount;p++) {
       if(containerID.getType() === "form") {
          itemList = containerID.getPage(get(pageList, p)).getChildren(); //get the page object from the form
       }
       
       //loop all the items
       for(var i=0; i<itemList.getLength(); i++)
        {
         var theItem = itemList.get(i);
         if(app.getSharedData().hasItems(theItem)) {
             //if container go into it...
               app.getSharedData().getItem(theItem, processItem);   
            } else {
               //other wise do something with the item
               if(dojo.isFunction(processItem)) { //make sure that the parameter passed is a function
                 processItem(theItem);        
                }
            }
        }
      }
}


Constrain Field Data Length

Description:

This function will restrict the field length of a field.  It will not allow anymore characters to be entered into the field once the limit is reached. 

Usage Notes:

Place this function in the Settings > Events

Navigate to the field where you want to constrain the length.In the onItemLiveChange event place the code below.

app.getSharedData().restrictFieldLength(item, 3);

This will limit the length to (3). You can adjust this number according to your needs.

Function:

app.getSharedData().restrictFieldLength = function(theField, theLength) {
  var v = theField.getDisplayValue();
  if(v.length >= theLength) {
    theField.setDisplayValue(v.substr(0,theLength));
  }
}