/
Rule Examples

frevvo Latest - This documentation is for frevvo v10.3. v10.3 is a Cloud Only release. Not for you? Earlier documentation is available too.

Rule Examples

Overview

This chapter contains numerous real world samples of the custom dynamic behaviors you can add to your forms and workflows. Many of the business rules described below are easily created with the frevvo Visual Rule Builder by simply selecting appropriate functions or controls from your forms/workflows using a visual wizard. Rules can still be written with JavaScript in order to build any degree of complex, powerful business logic and integrate with your Web Services and frevvo connectors.


Navigating this Page

This page is divided into the following sections. To search the headings and content, type Ctrl-f and enter a keyword.

SectionSubsectionsExamples
Rule Events

form.load | form.unload | form.activate

Rules by Function



Calculations

Control Types for Calculations | Addition | Multiplication | Calculate a Subtotal | Calculate a Grand Total | Round a Number | String Concatenation

Show/Hide Rules

Show/Hide based on a Control Value | Show/Hide if another Control is Filled | OR Conditions | Multiple Conditional Statements (if-else if) | Show a Tab on a Workflow Step | Show/Hide Submit and Cancel Buttons | Show/Hide Approval Sections on Workflow Steps

Control Property Rules 

Printable | Enable/Disable Submit and Continue Buttons | Enable/Disable a Control | Set Valid/Invalid Property | Set Error Message | Required Field Status in Accessible Forms | Dynamic Label, Help or Hint | Expand/Collapse Section | Select Tab | Next Tab | Pattern

Formatting Rules

Format Money Values to Display in a Message Control | Format Money in Text Controls | European Number Format | TextArea Max Length | Convert TextArea newline to HTML break | TextArea Wrap Long URL in PDF Snapshot |     Split Phone Number

Prefilling Rules

Tenants, Roles, and Users | Initialize Form with Current User Info | Populate Form with Any User's Info | Populate Dropdown with Users/Roles | Populate Dropdown with Roles Assigned to a User | List Users in a Role | List Users in Multiple Roles | List a User's Roles | Verify User | Verify Role | Unique and/or Sequential ID

Signatures

Signature via Web Service | Set Signed Date | Enable Click to Sign for Anonymous User

Doc Action, ADA, Precondition-Related

Conditionally Send Email

Rules by Control TypeSelection Controls

Options | Set Options | Set Options to Control Values | Default Selection | Display Selected Option Label | Clear Selections | Randomize Options | Dynamic Options | Options from a Database | Combobox Options from a Webservice Options from a Google Sheet | Synchronized Dropdowns | Find a Selected Options Index | Filter Dynamic Options | Triggers & Dynamic Options | Search a JSON String | Cascading Dropdowns | Dynamic Control Initialization with JSON

Comment Property Rules | Set Comment Field | Retrieve Comment Value | Set Max Length for Comment Field

Checkbox Control Checkbox Initialization | Display Selected Checkbox Labels | Checkbox isFilled Condition | Selected Checkbox Options in Conditions | Many Checkbox Comments | Set Options for a Checkbox to Values of Another Checkbox | Count the Options Selected | Repeating Checkboxes

T/F Boolean Control | T/F Value as Condition | Set a T/F Value | Clear a T/F Value


Date and Time Controls 

Working with Date and Time Rules

Set Dates and Times | Today's Date and Time | Date/Time Stamp | Create a Date, Time or DateTime Value | Set a Future Date | Set a Future Date Based on Five-Day Work Week | Get Day of Week from DateCalculate a Return Time | Time Zone Adjusted for Daylight Savings

Duration | Age | Stay Duration (Days) | Duration Including Start & End | Duration (Working Days) | Duration between Date/Time | Calculate Hours Apart | Calculate Time Between

Date Conditions Date No More Than x Days From Today | Date No More Than x Days Ago | Show Error Message if Date1 is On or Before Date2 | Display a Date in a Message Control

Checking a Date for Extra Digits | Copy Date, Time and DateTime Values


Repeats 

Show/Hide Controls in a Repeat | Repeat itemAdded Condition | Collapse Prior Items When Item is Added | Dynamically Set Min and Max in a Repeat | Repeat Item Initialization | Repeat itemAdded by Init Doc | Repeat Item Increment


Tables

Table Column and Cell Properties | Show/Hide a Column in a Table | Hide the Minus Icon on a Table Row | Dynamically Setting Min/Max in a Table | Populate Table Rows based on Query Results | Clear Values in a Table | Clickable Links in a Table | Set a Value Based on Table Rows | Count the Number of Items in a Table | Sort a Table by a Column Value


Upload Control

Display Uploaded Image | Dynamically Set Min/Max Properties | Upload Control Required/Optional | Count Uploaded Files | Display Uploaded File Names in a Dropdown | Rename an Uploaded File | Set Max Total Size for Submission


Message Control

Display Form Data | Display a PDF in a Message Control | Method 1: Host the PDF on your website | Method 2: Upload the PDF in frevvo's PDF Mapping tool | Display PDF with mapped fields | Embed a Video in a Message Control

Rules for Integration


Geolocation | Use Google Maps API to Calculate Mileage | Search Popup | LDAP Custom Attributes | REST Web Services

Rule Events

Whether you are using the Visual Rule Builder or editing Rule Code, it is helpful to understand some of the common events that you will use to trigger rules as they can affect the behavior of your forms/workflows. The following examples illustrate the use of form.load, form.unload, form.activate, and form.deactivate events. 

Refer to the When Do Rules Execute section for more information.

form.load

Rules can be used to initialize field values. This is a very useful feature and is often used to dynamically populate dropdown options from a database. Rules using form.load are triggered when a form first loads and when a workflow is loaded from a task list.

Rules using itemAdded only execute for repeat items added when the user clicks +, and for those added from an initial instance document (See Document URIs). It does '''not''' execute for those items that you have added to your form in the Form Designer. You can either add defaults directly via the form designer or add a 2nd rule to your form as follows.

These two rules together initialize the dropdown fields inside a repeat that is already in the form via the Form Designer, as well as those added each time a user clicks "+" on the repeat to add a new item & via initial documents. These controls are initialized based on a value set in another field.

Rule Code
//1st Rule - Default Items
if (form.load) 
{ 
    // The form contains two repeat items by default.
 
    if (department.value === 'Marketing') { 
        Managers[0].options = ['Joe', 'Mary', 'Stan', 'Cindy'];
        Managers[1].options = ['Joe', 'Mary', 'Stan', 'Cindy']; 
} 
    if (department.value === 'Sales') {
        Managers[0].options = ['Lou', 'George', 'Wendy']; 
        Managers[1].options = ['Lou', 'George', 'Wendy'];  
    } 
}
 
//2nd Rule - Items Added
if (Erepeat.itemAdded) 
{
    var index = Erepeat.itemIndex; // which item is this in the list  
    ES[index].value = 'Day'; // default the employee shift to day
 
    // Use options already selected in form.load rule 
    Managers[index].options = Managers[0].options; 
}

In the Rule Builder, designers can specify at the rule level whether or not a given rule is intended for initialization or not. Checking the Initialization Only checkbox on the wizards marks a rule as an initialization rule. If checked, the generated rule will be wrapped in an if (form.load) statement. The rest of the generated rule (conditions, actions, etc) will be contained within this if statement. The rule shown sets the field named name to "Paul" if the value of the Gender dropdown is "male" and the workflow is on the second step.

Rule Code
if (form.load) {
  if ((gender.value === 'male') && (frevvo.step.on('_8yjc0OSvEeafOKEJqSXZcw'))) {
    name.value = 'Paul';
  } else {
    name.value = null;
  }
}

 If this same rule is not marked for initialization, it will behave like an anytime rule which means that it will fire when the form loads as well as a control value change. The generated JavaScript will include:

var e = form.load;

form.unload

Rules including the form.unload event are not yet supported in the Visual Rules Builder and thus still requires some JavaScript. Rules can be used to finalize field values after the users clicks the form's submit button but prior to the Form and Doc Action execution. Rules using form.unload are triggered when the form user clicks the submit button and for workflows when the user clicks continue to go to the next activity or finish to complete the workflow.

One common example use is for an order form order number. You may only want to assign a unique sequential order number to each order submission. You could initialize the form's order number when the form loads using form.load. However, if someone starts filling in the order form but never submitted it you do not want to consume the next order number in sequence if it will never be used. Using form.unload you can assign the number after the submit button click but before the form data is submitted.

Here OrderNum is the name of invisible control.

Rule Code
/*member num */
var x;
 
if (form.unload) 
{ 
    eval('x=' + http.get('http://(your webhost)/json/getNextOrdernum'));  
    OrderNum.value = x.num;
}

If you have a rule in your form that changes any control(s) after clicking Submit, thereby making the form invalid, the form will no longer be submitted and the invalid form will redisplay. This change avoids creating an invalid xml for a successful submission.

This feature is implemented for forms only.

The form.deactivate event is identical to the form.unload event. Whenever a step gets deactivated in a screenflow or multi-user workflow, it is unloaded as well. form.deactivate was added for completeness. The rule in this example will also work if it was written using form.deactivate instead of form.activate.

form.activate

In a desktop browser, users can navigate back and forth between the steps of a frevvo screenflow or multi-user workflow using the Navigation toolbar. Previous and Next buttons are available on mobile devices for this functionality. Workflow designers should consider this navigation when writing business rules. Steps in a screenflow are read/write since they are all performed by the same user and editing is allowed.

form.load is only triggered when the step is loaded for the first time. This is not very efficient. form.activate triggers every time a read/write step is displayed. This makes form.activate and form.deactivate events that give designers a more reliable way to set properties for steps in a screenflow.

Let's take a look at a two step screenflow designed using Linked forms to illustrate these points. Step 1 has 2 text fields, Text 1 is visible and not required. Text 2 is initially not visible and not required. We added a rule in the Visual Rule Builder that sets Text2 to visible and required on Step 2. 

Rule List

Notice that by default the VRB creates the rule on the form.load event.

Rule Code Generated by Rule Builder
var event = form.load;
if (frevvo.step.on('_4neSkLpxEeu1dMbj8N29dg')) {
  Text2.visible = true;
  Text2.required = true;
} else {
  Text2.visible = false;
  Text2.required = false;
}


Let's see what events occur when Step 1 is loaded.

  • LOAD Step 1 – the form.load is triggered since step 1 is being run for the first time. Text 1 is visible and required and Text 2 is not visbile and not required
  • ACTIVATE Step 1 – activate triggers because the step is loaded for the first time.

The user clicks continue and the workflow navigates to Step 2. Note Step 1 is deactivated and unloaded and Step 2 is loaded and activated:

  • DEACTIVATE Step 1
  • UNLOAD Step 1
  • LOAD Step 2 – the workflow is on step 2 – the form.load triggers because step 2 is being loaded for the first time. Text 2 is now visible and required.
  • ACTIVATE Step 2 – this runs because step 2 is displayed.

The user navigates back to Step 1 without filling in Text 2. Note Step 2 is deactivated and unloaded and step 1 is activated.

  • DEACTIVATE Step 2
  • UNLOAD Step 2
  • ACTIVATE Step 1

form.load is not triggered, so Text 2 is not visible (due to initial property value) but it is still required because Step 1 did not LOAD again. When the user clicks Continue to move to Step 2 the screenflow does not move forward.

If the rule is written based on the form.activate event instead, here’s what happens. (In this case, we edited the rule code and changed form.load to form.activate.)

  • The user initiates the screenflow.
    • LOAD Step 1 – the form.load is triggered since step 1 is being run for the first time. Text 1 is visible and optional  and Text 2 is not visbile and not required
    • ACTIVATE Step 1 – activate triggers because the step is loaded for the first time
  • The user clicks continue and the workflow navigates to Step 2. Note Step 1 is deactivated and unloaded and Step 2 is loaded and activated.
    • DEACTIVATE Step 1
    • UNLOAD Step 1
    • LOAD Step 2 – the workflow is on Step 2 – the form.load triggers because Step 2 is being loaded for the first time. Text 2 is now visible and required. 
    • ACTIVATE Step 2 – this runs because step 2 is displayed.
  • The user navigates back to Step 1 without filling in Text 2. Note Step 1 is only activated.
    • DEACTIVATE Step 2
    • UNLOAD Step 2
    • ACTIVATE Step 1
  • The form.activate event is triggered, so the rule runs. The visible and required properties for Text 2 evaluate to false.
  • When the user clicks Continue to move to step 2 the screenflow moves forward. The user fills in Step 2, clicks Finish and completes the screenflow.

For multiuser workflows, form.load and form.activate are triggered when the step is displayed for the first time. form.activate is not triggred when navigating backwards via the Task List as these steps are Read Only. The Activity assigned to the current user will load only once but will activate every time they are loaded in a particular session.

Rules by Function

The examples in this section are organized by the rule's business function, i.e. calculations/mathematical rules, show/hide rules, and rules for various control properties.

Calculations | Show/Hide Rules | Control Property Rules | Formatting Rules | Prefilling Rules | Doc Action, Activity Doc Action, and Precondition-Related Rules

Calculations

Business logic that automatically calculates subtotals, total, and other math functions is easier for your users and prevents mathematical mistakes. Here are several common examples:

  • Expense Report Subtotals and Grand Totals
  • Time Sheets Hours per task, per day and per week
  • Purchase Order line item costs

Control Types for Calculations

When using the Visual Rule Builder for calculations, the expressions must have the same value type as the control. For example, math functions are only available on number, quantity, and money controls. If there is a type discrepancy, the VRB Help Mode will display a "Field type mismatch" error:

Let's say you have two Number controls that take a decimal, and you want to set the total in a Quantity control, which only takes a whole number. This rule is valid in the Visual Rule Builder. However, if the user enters values such that the sum is a decimal (such as "2.5"), the rule will set the value as requested, but will truncate the decimal in the total (Quantity) control, showing the value "2" instead of "2.5".

The Visual Rule Builder supports text-to-number conversion with the function number(). For example, you may want to calculate a total from two Text controls that contain numbers. Set Total to sum(number(Text1), number(Text2)) to convert the Text control strings to numbers.

Addition

Adding two or more values is a common and simple calculation. Let's take a form that has three Quantity controls named Q1 (Quantity 1), Q2 (Quantity 2) and T (Total). We want to add the values in Q1 and Q2 and display the result in the Total field. This rule will automatically fire whenever the user types something in Q1 or Q2 and will set the value of Total to their sum.

Action Wizard

You can use the sum function or just type Q1 + Q2 in the expression field.

Rule List

or...


How it works

 Click to learn how it works...

Click Rule Code to view the Javascript set by the Visual Rule Builder. It uses the standard Javascript assignment operator (=) to set the value of T, and the addition operator (+) to sum the values of Q1 and Q2.

Rule Code
var event = form.load;
T.value = Q1.value + Q2.value;

Multiplication

Multiplication is a common and simple calculation. Let's take a form that has a Price, Quantity and Total controls. We want to multiply Price times Quantity and display the results in the Total field.

Action Wizard

Rule List

How it works

 Click to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. It uses the standard JavaScript assignment operator (=) to set the value of Total, and the multiplication operator (*) to sum the values of Q1 and Q2. Notice that in this case the VRB has placed the expression inside parentheses. While not strictly necessary in this simple rule, the parenthesis act as a grouping operator to ensure the correct operation precedence for more complex calculations.

Rule Code
var event = form.load;
Total.value = (Price.value * Quantity.value);

Calculate a Subtotal

You can also use multiplication in a Table Control to display a subtotal for each row. The Visual Rule Builder automatically creates the code to handle adding/deleting table rows. Imagine a Purchase Order workflow with a Table control to list the items being ordered. The Table has columns for Price, Quantity and Subtotal. You want to multiply Price times Quantity and display the results in the Subtotal fields for each row in the table. 

Action Wizard

Rule List


How it works

 Click here to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. The Visual Rule Builder uses an if else statement (condition ? Value if True : Value if False) to assign a value to variables (Subtotal_start_index and Subtotal_end_index) whenever a row is added. Then it uses a for loop that iterates over the table setting Subtotal in each row ('i') to the result of the multiplication expression for that row. 

Rule Code
// if a row is added, set Subtotal_start_index to the index of that row. Else, set it to 0.
var Subtotal_start_index = Table1Repeat.itemAdded ? Table1Repeat.itemIndex : 0;
// if a row is added, set Subtotal_end_index to the Subtotal_start_index plus 1, else set it to the number of rows that have a value in the Subtotal column.
var Subtotal_end_index = Table1Repeat.itemAdded ? Subtotal_start_index + 1 : Subtotal.value.length;
var event = form.load;
for (let i = Subtotal_start_index; i < Subtotal_end_index; i++) {
  Subtotal[i].value = (Price[i].value * Quantity[i].value);
}



The sum() function mentioned above will calculate over the entire repeat/table. To use addition to subtotal individual rows, use the "+" operator, i.e. Set Subtotal to Item1 + Item2. 

Calculate a Grand Total

Consider a Purchase Order form with a table that calculates subtotals as described above. Now you want to add a Grand Total field to your Purchase Order workflow. The Grand Total field contains the sum of the Subtotal fields in each row of the table. Add a Money control to your form/workflow and name it Grand Total. Use the Rule Builder to create the rule. The Rule Builder automatically creates the code to handle adding/deleting table rows.

Action Wizard

Rule List

How it works

 Click here to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. The Visual Rule Builder uses a variables (sum_result) in a for loop to get the calculated total for the number of rows that have a value in Subtotal. The value of GrandTotal is set to that variable, updating whenever a row is added or removed.

Rule Code
var sum_result;
//run this rule whenever a table row is added or removed or the form loads
var event = ItemsTable.itemAdded || ItemsTable.itemRemoved || form.load;
sum_result = 0;
//loop through the table when Subtotal has a value, adding each Subtotal value to the variable sum_result
for (let i = 0; i < Subtotal.value.length; i++) {
  sum_result += Subtotal[i].value;
}

Round a Number

A common requirement is to set a display a number control with a specific number of decimal places. Let's say you have a Time Sheet where you collect the number of hours worked per day and total them in a Line Total field. Your form has a table with Number controls for the daily hours and a Number control for the total. When testing your form, you enter values with decimal points and notice the total unexpectedly calculates to a number with many decimal places. This is JavaScript behavior when calculating decimal point addition. You can use the round() function in the Visual Rule Builder to prevent this and round the Total Hours value to two decimal places.



Action Wizard

The round() function takes two parameters - number and decimal digits. In this example, we're adding several control values to get the number so we enter the addition operation inside parenthesis. The decimal digits parameter is 2.

At runtime, notice that Total Hours is now correctly rounded to two decimal places.

How it works

 Click to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. Because this example is a table, this rule loops through the table to set values on each row. It uses the JavaScript Math object with round function, which is a method for rounding to whole numbers. It then uses exponential notation ('e' + 2, 'e-' + 2) to round to the correct number of decimal places. 

Rule Code
var TotalHours_start_index = TimesheetTableRepeat.itemAdded ? TimesheetTableRepeat.itemIndex : 0;
var TotalHours_end_index = TimesheetTableRepeat.itemAdded ? TotalHours_start_index + 1 : TotalHours.value.length;
var event = form.load;
for (let i = TotalHours_start_index; i < TotalHours_end_index; i++) {
  TotalHours[i].value = Number(Math.round((Mon[i].value + Tue[i].value + Wed[i].value + Thu[i].value + Fri[i].value) + 'e' + 2) + 'e-' + 2);
}


You can also handle this in the Rule Code editor. Use the built-in toFixed(n) function to truncate the result to n number of decimal places.

Rule Code
var x;
x = (Mon.value + Tue.value + Wed.value + Thu.value + Fri.value);
LineTotal.value = x.toFixed(2);

Another approach would be to assign Patterns that limit the number of decimal places.

String Concatenation

The Visual Rule Builder can also handle string concatenation in the function concat(), which takes as many expressions as you want, each separated by a comma. Any literal values used as expressions should be placed inside quotes. For more information, read our documentation on writing rules with strings vs. numbers. In this example, we will create a rule with the Visual Rule Builder to concatenate the First Name and Last Name and display the results in the Fullname field.

Condition Wizard

Action Wizard

Else Action Wizard

Rule List

How it works

 Click to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. Notice that each expression on the right side of the value assignment is separated by a '+' operator. In JavaScript, the + operator will add numeric values but concatenate string values. See the Operators documentation for more info. The VRB uses the Boolean check in the if condition, but this is not strictly necessary. Writing if ((FirstName.value) && (LastName.value)) would work the same way.

Rule Code
var event = form.load;
if ((Boolean(FirstName.value)) && (Boolean(LastName.value))) {
  fullname.value = FirstName.value + ' ' + LastName.value;
} else {
  fullname.value = null;
}


Show/Hide Rules

Often forms/workflows need fields that are used conditionally, depending on the answers to other fields. For example, if your form requires both a Shipping Address and Billing Address but the user has checked "Shipping Address is the same as Billing Address" then it's nice to not clutter the form with the unnecessary Shipping Address input fields. You can use rules to hide the Shipping Address and show it only when the form user says they are different.

The easiest way to create a Show/Hide rule is to use the frevvo Visual Rule Builder. Here are common reasons for using Show/Hide:

  • Show/Hide a section
  • Show a Message to the user to alert them to either an error or success condition
  • Show a Details Text Area when as user clicks Yes to "Would you like to describe your issues in detail?"
  • Show a Signature or Signed Section when the workflow reaches the approval step
  • Show/Hide a Tab on a Workflow Step

See the documentation for Data Sources and Schemas for details on implementing a Show/Hide rule with XSD controls.

Show/Hide based on a Control Value

Consider a Purchase Order form that contains a Billing Address section, a hidden Shipping Address section a Radio control named DiffShip that asks the question, "Is the Shipping Address different from the Billing Address?" If the Billing and Shipping addresses are the same there is no need to clutter the form with unnecessary Shipping Address input fields. You can use a rule to hide the Shipping Address and show it only when the form user says they are different. This rule will automatically fire whenever the user changes the response to DiffShip and will show/hide the shipping address section. In this example, an Else Action is helpful so that when the form loads, and if the user changes a Yes response back to No, the section will be hidden.

Condition Wizard

The condition for this rule will be the value of the control DiffShip is the literal value "Yes". Be sure to click the toggle to "Enter a literal value" and use the Form Outline to be sure the value you enter matches the control's option value exactly (it is case sensitive.)

Action Wizard

Else Action Wizard


Rules List

How it works

 Click here to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. The Visual Rule Builder creates an if-else statement. Note that the control name "ShippingAddress" is following by the property indicator ".visible", which takes a boolean value of true or false.

Rule Code
var event = form.load;
if (DiffShip.value === 'Yes') {
  ShippingAddress.visible = true;
} else {
  ShippingAddress.visible = false;
}

Show/Hide if another Control is Filled

This rule makes the message control NicknameMsg visible when the user enters a value into the Nickname input text control. It also hides the message control if the user deletes the value in Nickname.

Condition Wizard

This condition makes use of the built-in function "is filled". It will run whenever the control Nickname has data entered in it.

Action Wizard

Else Action Wizard

Rules List

How it works

 Click here to learn how it works...

Click Rule Code to view the JavaScript set by the Visual Rule Builder. The Visual Rule Builder creates an if-else statement using "Boolean" to check if Nickname has a value. Boolean returns TRUE if Nickname has a value, and FALSE if it does not. The VRB uses the Boolean check in the if condition, but this is not strictly necessary.

Rule Code
var event = form.load;
if (Boolean(Nickname.value)) {
  NicknameMsg.visible = true;
} else {
  Nickname.visible = false;
}

OR Conditions

Here's another show/hide example where we are setting multiple conditions to show/hide a message control. This form has a radio control named Facility and a second radio control named CompanyFacility. This rule makes a message control named FacilityMessage visible depending on the selected options. If Boston is selected for the Facility control OR New York is selected for the CompanyFacility control, the hidden message control will display. 

Condition Wizard

Remember to change the "and" to "or" in the Logic expression so the rule will execute if either condition is met.

Action Wizard


Else Action Wizard

Rules List