This documentation is for frevvo v10.1. Not for you? Earlier documentation is available too.
Rules Examples (old)
This page is deprecated. Please see our new Rule Examples page to find the page you are looking for.
Looking for a section on this page? Hover your cursor over the Table of Contents icon to the right to quickly navigate this page.
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 Visual Rule Builder. This eliminates the need for the designer to write JavaScript. The Visual Rule Builder provides the functionality to add business logic by simply selecting appropriate functions or controls from your forms/workflows using a visual wizard.
The Visual Rule Builder provides the following functions:
Use the Operators listed below to build the rule expression:
Rules can still be written by manually adding JavaScript in order to build any degree of complex & powerful business logic and integrate with all or your Web Services and frevvo connectors.
Refer to the Visual Rule Builder chapter or watch this webinar for an overview of how to create dynamic forms/workflows without writing code.
Calculate Totals
Forms are easier for your users with business logic that automatically calculates subtotals, total, etc.. Here are several common examples:
- Expense Report Subtotals and Grand Totals.
- Time Sheets Hours per task, per day and week
- Purchase Order line Item Costs
Add two fields
Your form has three Quantity controls named Q1, Q2 and T respectively. You want to add the values in Q1 and Q2 and display the result in the Total Quantity field. This rule will automatically fire whenever the user types something in Q1 or Q2 and will set the value of Total Quantity appropriately. However, it's important to ensure that the calculated value is valid with respect to the type of Total Quantity. For example, if Total Quantity was of type integer and the computed value of the expression was decimal (such as 1.5), then the rule would be attempting to set an invalid value in T. This is an error. The rule will set the value as requested, but will mark the field as invalid and take appropriate action such as disabling the submit button, displaying the control with a red background etc. Also, if controls are added to the form from the palette, it is important to ensure they have the correct type. For example, for a numeric calculation as described above, the controls should be of type Numeric (found in the palette). 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 contains numbers. Set Total to number(Text1) + number(Text2) to convert the Text control strings to numbers.
You can use the sum function or just type Q1 + Q2 in the expression field
Action Wizard
Rule List
Rule List
Multiply Price times Quantity and display results in a Total field
Your form/workflow has a Price, Quantity and Total Quantity controls. You want to multiply Price times Quantity and display the results in the Total field.
Action Wizard
Rule List
Calculate a Subtotal
Imagine you have an Purchase Order workflow with a Table control. The Table has Price,Quantity and a Subtotal column. The fields are namedTPrice,TQuantity and Subtotal. You want to multiply TPrice timesTQuantity and display the results in the Subtotal fields for all the rows in the table. The Rule Builder automatically creates the code to handle adding/deleting table rows.
Action Wizard
Rule List
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
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
Show or Hide Controls and Workflow Steps
Often forms/workflows need fields that are only used depending on the answers to prior form fields. For example, if your form requires both a Shipping Address and Billing Address but the your form user has checked "Shipping 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 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 the Shipping Address if it is different from the Billing Address
Show a Message based on Selections in Other controls
Show a Message if a control contains data
Show Tabs on specified workflow steps
Show/Hide Submit & Cancel
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
You have a form with multiple tabs. The main tab contains the form and the other tabs contain reference information users may need when completing the form. You only want the submit and cancel buttons visible when the user is in the main tab. This rule hides the submit and cancel buttons when the reference tabs are selected. The control name of the main tab is MainTab. Be sure to select the Main Tab in the designer then save the form. This ensures the Main Tab will be selected when the form loads and the rule will run.
You can write the rule using the if...else conditional statement shown in the example on the left or the shortened syntax shown on the right:
if (!(MainTab.selected)) { Submit.visible = false; Cancel.visible = false; } else { Submit.visible = true; Cancel.visible = true; }
Submit.visible = Cancel.visible = (MainTab.selected);
Show/Hide Approval Sections on specified workflow steps
Printable
Business rules often are used to control what is printed to the final form PDF.
This form has a radio control named DescribeInDetail and a section control named Details. Details is hidden by default and made visible if the user selects 'Yes'.
When the form is submitted we've configured to send an email with the form PDF. We only want the Details section to appear on the PDF when the user selects 'Yes'. So we uncheck the printable property on the section control. This property will apply to the section and all controls inside the section. So we do not have to uncheck printable on the inner controls. Then we create this business rule with the Visual Rule Builder. When the section is visible we also set it to be printable. When the section is hidden we also set it to be not printable.
Dynamically Send Email
Let's say you have a form or workflow step that should send an email only under certain conditions. In the example below, the Account Receivable form will only send an email to the Client Services Manager if the payment is related to a services project.
Enable/Disable Controls
Submit/Continue Button Disabled
A great feature of is the fact that a form cannot be submitted or a workflow cannot be continued to the next step until all required fields are filled and all filled fields have valid data (eg. a date field must contain a valid date). Sometimes it might not be as obvious to the form/workflow user why the form/workflow will not submit or continue to the next step. provides a built-in feature to show validation errors at the time of submission. Refer to the Invalid Form Notification for Users topic to see how it works.
Enable/disable a question
You have a form with two controls named Attending and Presenter respectively. Attending is a checkbox with a single option, Yes. If checked, you wish to ask the addition question, Presenter. Use the Rule Builder to create this rule. Be sure to slide the toggle icon to enter the literal value Yes on the Condition wizard.
This rule will automatically fire whenever the user checks or unchecks Attending and will enable/disable Presenter. In this example, you would typically set the checkbox Attending to be initially unchecked and the radio control Presenter to be initially disabled.
Formatting money values to display in a Message Control
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
Let's say you have calculated a sum in a Number control in your form and you want to display it in a Message control and format it as a money value with commas and decimal places. You will need a Number control named Num and a message control named Message in your form. This rule will display the number entered in the number control with commas. If the user enters 5600.44 in the number field then the result in the message control would look like this:"$5,600.44".
var x, x1, x2; if (Num.value > 0) { var nStr = Num.value.toFixed(2); nStr += ''; x = nStr.split('.'); x1 = x[0]; x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } Message.value = '$' + x1 + x2; }
Format Money in Text Controls
This rule is not yet supported in the Visual Rule Builder and thus still requires some JavaScript.
You may want to format money with currency signs, commas, decimals and rounded to two decimal places. This example uses a text control for input and a business rule to format the money value.
var x, x1, x2; var numberWithCommas = function(x) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }; var formatMoney = function(amt) { var decimalAmount = Math.round(amt * 100) / 100; return numberWithCommas(decimalAmount.toFixed(2)); }; if (Amount.value.length > 0) { var m = Amount.value.replace(/\$/g,"").replace(/,/g, ""); var formattedMoney = formatMoney(m); Amount.value = '$' + formattedMoney; }
Here is another example showing a text control named "Money" in a table. Another text control named "Total" displays the column total.
var x, x1, x2; var tot = 0; var numberWithCommas = function(x) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }; var formatMoney = function(amt) { var decimalAmount = Math.round(amt * 100) / 100; return numberWithCommas(decimalAmount.toFixed(2)); }; if (Money.value.length > 0) { for (var i = 0; i < Money.value.length; i++) { var m = Money[i].value.replace(/\$/g,"").replace(/,/g, ""); var formattedMoney = formatMoney(m); Money[i].value = '$' + formattedMoney; tot = tot + Number(m); } var formattedTotal = formatMoney(tot); Total.value = '$' + formattedTotal; }
European Number Format
You may need to display numbers in a locale-specific format. While current versions of frevvo do not support javascript locale methods on number controls, you can write a business rule to handle displaying numbers in your desired format. This example displays a number with a period as the thousands separator and a comma as the decimal separator, i.e. 10.000,00. You can modify this rule slightly for other formats, such as using a space as the thousands separator.
There is a text control in the form named EuropeanFormat.
//use a decimal as thousand separator var numberWithDecimals = function(x) { return x.replace(/\B(?=(\d{3})+(?!\d))/g, "."); }; //format with two decimals var formatNumber = function(amt) { var decimalAmount = Math.round(amt * 100) / 100; // this adds a decimal with two zeros after the number. return numberWithDecimals(decimalAmount.toFixed(2)); }; if (Boolean(EuropeanFormat.value) && Boolean(EuropeanFormat.value)) { var e = parseInt(EuropeanFormat.value.replace(/,/g, ''), 10); var f = formatNumber(e); //format the value using above functions var intIndex = f.lastIndexOf("."); f = f.slice(0, intIndex) + f.slice(intIndex).replace(".", ",");//change the last decimal to a comma EuropeanFormat.value = f; }
Here is the form in use mode:
This rule is similar to the format money rule above, in that it adds a decimal with two zeroes behind the number entered, so 12345 displays as 12.345,00. If you'd rather convert the number to a decimal as entered, simply remove the '* 100' from the Math.round() method parameters. This change will display 12345 as 123,45.
Rounding a Number to a Specified 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 consists of Number controls for the 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.
var x; x = (testone.value + testtwo.value + testthree.value + testfour.value + testfive.value + testsix.value); LineTotal.value = x.toFixed(2);
Another approach would be to assign Patterns that limit the number of decimal places.
Textarea Max Length
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
In html there is no way to set a maxLength on a textarea control. This is why the textarea control does not have a maxlength property like the text control does. It is possible to do this via a business rule. This example form has a textarea control named 'Desc' where the user can enter up to a 500 character description. On this control we also set the ErrorMsg property to the string 'You must limit your description to 500 characters'. This message is automatically displayed when the description control is set to invalid by the following business rule.
if (Desc.value.length > 500) { Desc.valid = false; } else { Desc.valid = true; }
You can even customize the error message by adding this line to your rule. Now the error message will tell the user how many characters they are over the maximum allowed.
Desc.status = 'Invalid. Max 20 chars allowed and you have ' + Desc.value.length;
Required Field Status in Accessible Forms
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
You can build forms/workflows In that meet Section 508 and WCAG 2.0 accessibility standards. Accessible forms/workflows can assist users with visual and motor impairments. When the Accessible property is enabled for a form/workflow, the error, "You can't leave this empty <control name>" displays, if users move ahead from a required field without filling it. The status property for the empty control becomes invalid and sets the error message. Normally, the status property can be used in a business rule. For example, let's say a form has a text control named 't', and a message control named "m". If you write a rule to update the message field (control named m) with the STATUS of the required/invalid control (control named t), as shown below, it will not work because the "You can't leave this empty" message for a required control is not treated as it's status.
if(!t.valid) { m.value = t.status; }
If the rule is written this way, it will fill the message control with the errmsg from the invalid text control.
if (!t.valid) { if (t.value.length === 0) { m.value = "You can't leave this empty." } else { m.value = t.status; } }
Textarea newline vs break
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
Users typically enter multi-line text into textarea controls. If you want to display that text in an html context, for example on a web page or in an html formatted email or in your form's Form Action display message you will need to replace newlines with html breaks. This caused by the fact that line breaks entered into a web form textarea are represented by a single newline character \n while line breaks in an html context are represented by the html break characters.
Our example has a textarea control named Description and a hidden control named DF. The user types into the visible control named Description and a business rules converts the newline characters \n into html breaks.
var x = Description.value; x = x.replace(/\\r/g,""); x = x.replace(/\\n/g,"<br/>"); DF.value = x;
This rule is also helpful if you are populating a Message control with a value from another Message control whose text was set using the Rich Text Editor. In this scenario, you can simply replace the /n line break with an empty string.
x = x.replace(/\\n/g,"");
Remember that in order to reference Message control values in a rule, the control must have Save Value checked in the properties panel.
Textarea Wrap Long URL in PDF Snapshot
This rule is not yet supported in the Visual Rule Builder so still requires some Javascript.
If users enter a long URL into a Textarea control, it appears wrapped in use mode but does not wrap in the PDF snapshot. Here is a rule to ensure text wraps in the PDF snapshot if needed.
var str; if (form.unload) { str = Source.value; //Source is the name of Text Area where user enters the URL. var result = ''; while (str.length > 0) { result += str.substring(0, 20) + '\n'; //The 2nd number '20' is the number of characters per line. Adjust this based on the width of your textarea control. str = str.substring(20); //See note above } Source.value = result; }
Selection Controls
Dropdowns, Checkboxes, Radio, ComboBox and T/F controls are selection controls. Populating selection control options to to create dynamic or static pick lists is a very common feature. Here are some of the top reasons you may want to do this:
- List of products for a Sales Order / PO
- Number of available vacation days for a Leave Approval
- List of projects for a Time Sheet
and many more....
You may want to populate selection control options by pulling from a web service or database. You can do this without writing an JavaScript code with the Dynamic Options feature.
Some of the rules discussed below require a business rule written in JavaScript and other are quickly and easily created with the Visual Rule Builder.
Dropdown Options
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
This example automatically sets the option selected in one dropdown based on the option selected in another. This is often useful when you have a form with choices that were dynamically populated. For example, imagine product choices which are descriptive text. When the user selects a product, your form needs to perform an action based on a product ID rather than the descriptive product text. A nice way to do this is to have the rule that dynamically populates the product choices dropdown also populate a product ID dropdown which remains an invisible control in the form. The product choices dropdown control was named Products and the product ID dropdown control was named PID
The 1st rule "Load Products" populates both the visible and hidden dropdowns with options from a database.
/*member productCode, productName, resultSet*/ var x; if (form.load) { eval('x=' + http.get('https://app.frevvo.com/database/BIRT/allProducts')); var opts1 = []; var opts2 = []; for (var i=0; i < x.resultSet.length; i++) { if (x.resultSet[i]) { opts1[i] = x.resultSet[i].productName; opts2[i] = x.resultSet[i].productCode; } } Products.options = opts1; PID.options = opts2; Products.value = opts1[0]; // default to 1st product option PID.value = opts2[0]; }
Finding a Selected Options Index
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
The 2nd rule Select Product ID keeps the hidden PID dropdown synchronized with the visible Products dropdown.
if (Products.value.length > 0) { var i; for (var x in Products.options) { if ((Products.value + '=' + Products.value) === Products.options[x]){ i = Products.options.indexOf(Products.options[x]); } } PID.value = PID.options[i].split('=')[0]; }
Rules using hidden dropdowns to keep descriptive option labels visible to the user while keeping cryptic database values hidden are often no longer necessary. Dropdown options have values distinct from the human visible option labels. The above can now be achieved with a single simpler rule:
/*member description productId resultSet */ var x, opts1; for (var i=0; i < x.resultSet.length; i++) { if (x.resultSet[i]) { opts1[i] = x.resultSet[i].productId+ '=' + x.resultSet[i].description; } } Rdocnum.options = opts1;
Here is another rule that dynamically populates both the product choices and product ID dropdowns. This rule calls a REST Service which returns an object rather than the resultset returned by the database connector as shown above. See the section on dynamic content for more details.
/*member ids products */ var x; if (S.value.length > 0) { eval('x=' + http.get('http://localhost:8182/products/?category=' + S.value)); P.options = x.products; ID.options = x.ids; }
Synchronized Selects
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
The Product Search example above is often used in conjunction with a hidden select control. Imagine that your database table contains a list of products. Each product has product description also a unique product ID. The user needs to select a product from a dropdown on your form. You want to populate the dropdown with the product descriptions. The users do not need to see or know the product IDs but you need to use the ID as the key into the database for other selects. To do this add another hidden dropdown to the form and populate it with the IDs. This example has a visible dropdown name Products and an invisible dropdown named PID. See the rule above that populates these dropdowns dynamically from the database.
This rule below keeps the PID selected option in sync with the selected Product.
var i, x; for (x in Products.options) { // Determine the index of the selected product in the Products dropdown options if (Products.value === Products.options[x]) i = Products.options.indexOf(Products.options[x]); } // Changed the selected PID to match the selected Product PID.value = PID.options[i] + '';
Clearing Dropdown Options
This sample resets a dropdown option to the automatically added blank option. For dropdowns added from palette controls and from schema, automatically adds a blank option so the dropdown initially shows no choice by default. To reset the dropdown, set the dropdown control's value to null not the empty string. The empty string will not work since the empty string is not a valid option. This form resets the dropdown named size whenever the value of the product option changes.
Filter Dynamic Options
You may want to filter the dynamic options before setting the value of your dropdown control. For example, perhaps you want to populate options from a database while excluding any option with the value of 0. Use a rule like this.
if (tr.clicked) { var opts = []; var j = 0; for (var i=0; i<dd.options.length; i++) { var opt = dd.options[i]; // filter out the one with a 0 for value if (opt.split("=")[0] != "0") { opts[j] = dd.options[i]; j++; } } // put the filtered options back dd.options = opts; }
Default Options
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. When your options are set dynamically as shown below in a business rule, you cannot set a default in on the form designer. You need to set the default in the rule. If your options have <value>=<label> where value is different from label, make sure you set the <control>.value to <value> not <label> and not <value>=<label>
if (form.load) { var cc = ['R=Red', 'B=Blue', 'G=Green']; Colors.options = cc; Colors.value = 'B'; }
Display Selected Option Label
One common use for the Dropdown control is to allow the person completing the form to select who will perform the next step from a list of users. In this case, the designer may set up the Dropdown options with the userId as the option value (to ensure a valid user assignment when this field is used as a template in the Assignment tab), but a friendly name, such as the user's first and last name, as the option label. However, since the form user does not know that the value does not equal the label, when they search their tasks or submissions for 'First Name Last Name', they see no results because they should be searching for userId.
You can use this business rule to display the Dropdown's option label in a hidden field, and then set that hidden field as the Searchable Field for users to search task list or submissions by. Here's an example of a dropdown where the options value and label are different. Notice that we have a hidden control beside it to collect the selected option's label:
This rule is not yet available in the Visual Rule Builder, and will require some javascript. Create a new rule, click Rule Code, and then Edit Rule Code. Add this code (replacing the control names with your control names.)
var x; var selectedcolors = ''; var v = AsssignStep2To.value; for (x in AsssignStep2To.options) { var opt = AsssignStep2To.options[x]; var val= opt.split('=')[0]; var lab= opt.split('=')[1]; if (v === val) { selectedcolors = selectedcolors + ' ' + lab; } } SelectedOptionLabel.value = selectedcolors;
The result is that when an option is selected from the dropdown, we pass the option value in the dropdown control, and the option label in the hidden control. The Selected Option Label control is visible here in use mode for demo purposes:
In the Workflow Settings Searchable Fields tab, select the hidden field (in this example, "Selected Option Label") instead of the dropdown control itself. This allows your users to search by the option label, set in the hidden field, rather than the Dropdown value, which they do not know.
For Checkbox controls, see this rule example to display all selected option labels.
Populate a Pick List from a Google Sheet
Dropdown control options can be dynamically populated from a Google Sheet using a business rule. Refer to Create a Dynamic Pick List from a Google Sheet for the relevant details.
Set Options based on Values from Other Controls
You may wish to customize your selection control options at runtime based on values in other form controls. Unlike other control properties, options do not support templatized strings, so you will have to write a rule to set the options.
Let's say you have a form that asks the user to enter three items, and then select their top choice from those three items. You have three text controls (Item1, Item2, and Item3) and a radio control (TopChoice). Write your rule as follows:
var opt = ['I choose ' + Item1.value,'I choose ' + Item2.value, 'I choose ' + Item3.value]; TopChoice.options = opt;
The run time result will look like this:
Randomize Options
You may want the options of a selection control to appear at random each time a user opens the form, such as in a quiz. Add your selection control and options.
Then, add this rule:
var points = select.options; if (form.load) { points.sort(function(a, b) { return 0.5 - Math.random(); }); } select.options = points;
Each time you load the form, you will see the options in a different, random order.
Checkbox Options
Checkbox controls are different from all other palette controls in that they are multi-select. Therefore the way to write rules with checkbox controls are in many ways similar to rules with repeat controls.
Checkbox Options - Assigning Colors as Checkbox Options
This rule has a checkbox control named ColorPalette with the options: purple, green, blue, yellow, orange. The form also contains a text control with name ColorChoice. This rule assigns the choices selected from ColorPalette to ColorChoices.
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
var choices = ''; for (var i = 0; i < ColorPalette.value.length; i++) { choices = choices + ColorPalette.value[i] + " "; } ColorChoice.value = choices;
Notice that similar to repeat controls, due to an internal evaluation limitation, you must collect the choices in a variable inside the for loop. And then assign that control Name.value to that variable outside the for loop.
Checkbox Options - Changing the Label of another control
Another example showing how checkbox controls are array types is shown here. This rule can be created with the Rule Builder. Using the same form as the example above, this rule changes the Label of the Color Choice control to "Thank You for choosing colors" if options are checked in the Color Palette control. If there are no options checked then the Label of the Color Choice text control is "Please choose Colors...". The rule shown above assigns the choices selected from the control named ColorPalette to the control named ColorChoices
Checkbox Options - Making a Control Visible/Invisible
This rule makes visible/invisible a control based on which checkbox options a user selects. This form contains a multi select checkbox named Structures. If the user selects the option "Detached Garage" or "House", we want to make visible a text field named StructureDetails.
Again since a checkbox is multi select, it is handled as an array. The array will contain all selected (checked) options.
It is important to note that when a checkbox is added to the form from the palette and its options are multiple words containing spaces, the option array has converted each space character to the '_' character. We must make the comparison as shown below. Checkbox controls from schema do not have space replaced with '_'.
Note that when we hide Details we also clear its value. This is because the user may have selected one of the Structures checkboxes that made Details visible AND entered a value into Details. And then they may have changed their minds and uncheck the option that caused Details to become visible. If you don't want the value entered into Details to be in your form submission, clear the value when hiding it.
Many Checkbox Comments
This rule, as written, is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. You can achieve the same result in the Rule Builder but you must create a six separate rules to show/hide the details section for each option in your selection control. Expand the section after the example for details about how to create this rule in the Rule Builder.
This rule makes an associated comment input control visible and required when a checkbox is checked. The for loop determines which checkboxes are checked and sets an appropriately named variable to true. Depending on the value of the checkbox the associated input control will be made visible and required via the if/else and will be hidden and not-required when it is unchecked again. This is a very common rule design pattern.
This form uses the Compact layout to align the comment input controls with the checkbox options. Download a working sample that uses JavaScript rules here.
var heartProblem = false; var foodAllergy = false; var rashes = false; var jointInjury = false; var asthma = false; var moodiness = false; for (var i = 0; i < MedicalIssues.value.length; i++) { if (MedicalIssues[i].value === 'heart_problem') { heartProblem = true; } else if (MedicalIssues[i].value === 'food_allergy') { foodAllergy = true; } else if (MedicalIssues[i].value === 'rashes') { rashes = true; } else if (MedicalIssues[i].value === 'joint_injury') { jointInjury = true; } else if (MedicalIssues[i].value === 'asthma') { asthma = true; } else if (MedicalIssues[i].value === 'moodiness') { moodiness = true; } } if (heartProblem === true) { heartProblemDetails.visible = true; heartProblemDetails.required = true; } else { heartProblemDetails.visible = false; heartProblemDetails.required = false; //heartProblemDetails.value = null; } if (foodAllergy === true) { foodAllergyDetails.visible = true; foodAllergyDetails.required = true; } else { foodAllergyDetails.visible = false; foodAllergyDetails.required = false; //foodAllergyDetails.value = null; } if (rashes === true) { rashesDetails.visible = true; rashesDetails.required = true; } else { rashesDetails.visible = false; rashesDetails.required = false; //rashesDetails.value = null; } if (jointInjury === true) { jointInjuryDetails.visible = true; jointInjuryDetails.required = true; } else { jointInjuryDetails.visible = false; jointInjuryDetails.required = false; //jointInjuryDetails.value = null; } if (asthma === true) { asthmaDetails.visible = true; asthmaDetails.required = true; } else { asthmaDetails.visible = false; asthmaDetails.required = false; //asthmaDetails.value = null; } if (moodiness === true) { moodinessDetails.visible = true; moodinessDetails.required = true; } else { moodinessDetails.visible = false; moodinessDetails.required = false; //moodinessDetails.value = null; }
Checkbox Initialization
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
Since checkbox options are multi-select, in order to select multiple options via a rule you must use this syntax. The correct way to initialize the checkbox control value is to collect all required options in an array and then assign that array as the value of your checkbox control. In this example CB is the name of a checkbox controls with the following options: red, green, blue. This rule selects all of the options.
CB.value = ['red', 'green', 'blue'];
To clear all checked options in the control named CB:
CB.value = [];
Displaying Selected Checkbox Labels
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. In this example, the rule displays the labels of the checkboxes the user selects.
var x; var selectedcolors = ''; for (var i = 0; i < RGB.value.length; i++) { var v = RGB[i].value; for (x in RGB.options) { var opt = RGB.options[x]; var val= opt.split('=')[0]; var lab= opt.split('=')[1]; if (v === val) { selectedcolors = selectedcolors + ' ' + lab; } } } SelectedColors.value = selectedcolors;
Set Options for a Checkbox based on Values Selected in another Checkbox
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. This rule will take values selected in one checkbox control and populates those as options in a second checkbox control. For example, a checkbox control (Services) displays all available services. The second checkbox (Selected Services) will display as options the values selected in Services. One scenario you might use this is to customize an employee scheduling form. In Step 1 of the workflow the Coordinator picks the offered services from the full Program Service list. In Step 2 the Employee sees only the smaller list to select from.
var opts = ['']; for (var i = 0; i < ProgramService.value.length; i++ ){ var v = ProgramService.value[i].replace(/_/g," "); opts[i] = ProgramService[i].value + "=" + v; } SelectedPS.options = opts; var event = form.load;
Count the Number of Options Selected
There are use cases where you may want a total of how many checkbox options were selected. For example, one or more checkboxes may display a list(s) of products, and you want to know how many total products were selected. A simple rule will count the number of options selected where the checkboxes are named "Accessories," "Shoes," and "Jewelry" and the count is given in a Quantity control named "Quantity":
Quantity.value = Accessories.value.length + Shoes.value.length + Jewelry.value.length;
Retrieving or Setting the Comment Property for Selection Controls
Dropdowns, Checkboxes and Radio controls have the capability to display a Comment field if the user selects the last option. It is most often used as an "Other - please specify" option. In the Forms designer, check the Comment checkbox in the Properties panel and provide a # of rows for the comment area. If the user selects this option, a comment box will appear below asking the user to provide details. Selecting or unselecting the comment property is not supported in rules; however, business rules can be used to set or retrieve the value in the comment field.
The Visual Rule Builder can be used to set the comment field to a value or expression.
Business rules can be written to retrieve the value of the Comment field using the commentValue property. Note that the initial value of the commentValue is null. Your rules may have to be coded to check for that. This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
This simple rule copies the value in the comment field of a dropdown control named Supervisor to a text field named. The rule will run only if the value in the comment field is not null.
if(Supervisor.commentValue != null){ OtherSupervisor.value =Supervisor.commentValue; } else { OtherSupervisor.value = ""; }
Review this special syntax to reference comment fields in templates.
Set Max Length for Comment Field
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
You may need to set a max character limit on the comment box of a selection control. Use this rule example for a control named "Reason."
if(Reason.commentValue){ if(Reason.commentValue.length > 50 && TransferReason.value){ Reason.valid = false; Reason.status = 'Invalid. Max 50 chars allowed and you have ' + Reason.commentValue.length; } else { Reason.valid = true; } }
T/F Boolean
Use the Rule Builder to create a rule involving T/F controls. T/F controls are simplified checkbox controls with only a single visible option. This rule makes the control named "Agreement" visible if the T/F control named "Agree1" is checked and invisible if the T/F control named "Agree1" is unchecked.
The value property for a Boolean checkbox behaves differently depending on whether it is from schema or not. If the T/F control is from schema, you will see control.value === true
in the rule when the Boolean is checked.. If the T/F control is dnd from the palette, you will see control.value[0] === 'true'
in the rule when the Boolean is checked. Note the array syntax used in the rule when the T/F control comes from the Palette. Designer should be aware of this difference when manually writing JavaScript.
If you use the Rule Builder, this difference will be seamless to the designer.
For example, the rule for a Boolean control from schema generated by the Rule Builder looks like this
var event = form.load; if (Agree1.value === true) { Agreement.visible = true; } else { Agreement.visible = false; }
And the code for a Boolean control from the palette, looks like this. .
var event = form.load; if (Agree1.value[0] === 'true') { Agreement.visible = true; } else { Agreement.visible = false; }
Repeating Checkboxes
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. Checkboxes inside repeat controls must be treated as an array (each checkbox control's values) of checkbox option values which is inside another array (the repeating checkbox control itself). This form example has a repeating section containing two controls -- Message which is a text control and AreYouAttending which is a checkbox control with a single option 'yes'. To access the selected options the syntax is:
AreYouAttending[i].value[0] === 'yes'
for (var i = 0; i < AreYouAttending.value.length; i++) { if (AreYouAttending[i].value[0] === 'yes') { Message[i].value = Name.value + ' is attending event #' + i; } }
String Concatenation
Message controls can be used in business rules to create Summary information on your form from values entered into earlier form fields. Using templates in the Message control in combination with a business rule created in the Rule Builder make creating the Summary easy.
This form has fields to collect First Name, Last Name, Telephone Number, a Personal Email Address, a hidden field named fullname and a Message control named BasicSummaryMsg. The Summary Message control will show the entered Full Name, Telephone Number and Personal Email Address. We would like to show
- Click on the Message control.
- Slide the Rich Text Editor. Then click Edit with rich text editor. toggle switch on the Message control Property panel to turn on the
- Type the desired text into the Editor - for this example, type Name, Phone and Email labels followed by the {Fullname}, {Phone} and {Fullname} templates
- Select formatting options from the Rich Text Editor menu.
- Create a rule with the Visual Rule Builder to concatenate the First Name and Last Name and display the results in the Fullname field.
Dynamic Labels, Help or Hints
You can set the value of control labels, help and hint dynamically in a rule. For example imagine you do not know the label, help or hint at design time but would rather set it dynamically at run time. Create this rule using the Rule Builder.
In the above example the label, help and hint is still hard-coded. It's just being set from the rule rather than in the form designer control properties. To make this more useful you can initialize these properties from _data parameters:
if (form.load) { Text99.label = _data.getParameter('label'); Text99.hint = _data.getParameter('hint'); Text99.help = _data.getParameter('help'); }
Since _data.getParameter enables access to values passed to the form that are not bound to actual controls this is often a very useful pattern. This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript.
Select Tab
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. This rule makes a specific tab the selected tab based on the choice of a radio control. The radio is named SelectTab and has three options: Person, Auto, Home. The tabs are named personTab, autoTab and homeTab. Tabs also can be selected based on trigger controls or other input controls using the same method show here.
if (SelectTab.value.length > 0) { autoTab.selected = false; homeTab.selected = false; personTab.selected = false; if (SelectTab.value === 'Auto') { autoTab.selected = true; } else if (SelectTab.value === 'Home') { homeTab.selected = true; } else { personTab.selected = true; } }
Next Tab
This rule is not yet supported in the Visual Rules Builder and thus still requires some JavaScript. This form contains a trigger control at the bottom of each tab labeled "Next". When "Next" is clicked the trigger rule executes and makes the next tab the selected tab. This assists the user in navigating through the form. The Tabs are named T1, T2, T3, T4. The trigger controls are named C1, C2, C3
// Navigate Tabs if (C1.clicked) { T2.selected = true; } else if (C2.clicked) { T3.selected = true; } else if (C3.clicked) { T4.selected = true; }
Expand/Collapse Section
This form has three sections. The first section is expanded and the 2nd and 3rd are collapsed. When the user fills in the 1st section they click a "Next" trigger control which causes that section to collapse and the next section to expand. The trigger controls are named next1 and next2. And the sections are named: step1, step2, step3. Use the Rule Builder to create these rules. You will have to create 2 separate rules - one for Step 1 and one for Step2.
Multiple Choice
This rule makes the appropriate input text controls visible depending on the choice a user makes in a radio option controls searchChoice.
if (searchChoice.value === 'Organizations') { orgname.visible = true; firstname.visible = false; lastname.visible = false; clientId.visible = false; } else if (searchChoice.value === 'Individuals') { orgname.visible = false; firstname.visible = true; lastname.visible = true; clientId.visible = false; } else if (searchChoice.value === 'Client ID') { orgname.visible = false; firstname.visible = false; lastname.visible = false; clientId.visible = true; }
To achieve the same result using the Rule Builder, you must create 3 separate rules - one if the choice is Organizations, a second rule if the choice is Individuals and a third rule if the choice is Client Id.
Dynamic Options
The Dynamic Options rules discussed in this section are not yet supported in the Visual Rules Builder and thus still require some JavaScript.
Selection controls' (radios, checkboxes, dropdowns, T/F) options can be set dynamically via rules rather than statically via the control's options property. However if the control comes from an XSD schema data source rather than one of the standard palette controls, then the designer must take care to not set the options to something outside of what is valid for that schema element. For example if your XSD has a string enumeration and list valid options as 'red', 'green', and 'blue', then you should not use a rule to dynamically set the options to 'small', 'medium', 'large'. If you do then then your form will not work correctly in use mode. If a user selects the option 'small' they will get a validation error on the form. This is because 'small' is not one of the options allowed by your underlying XSD schema.
Triggers & Dynamic Options
This rule is executed when the user clicks the trigger controls with Name ''search''. It then dynamically sets options on a dropdown list control with Name coffeeShopList.
if (search.clicked) { coffeeShopList.options = ['Koffee', 'Starbucks', 'Willoughbys', 'Dunkin Donuts']; }
Now replace the hard coded list of coffee shops with a rule that invokes an http.get. This must return an X-JSON header which contains a JSON object. The object is evaluated and assigned to the variable x. In this case the JSON object contains an options field of type array. See the section on dynamic content for more details.
var x; if (search.clicked) { eval('x=' + http.get('http://(your webhost)/getCoffeeShopList')); coffeeShopList.options = x.options; }
Triggers do not work in repeating items.
Search a JSON String
This rule searches a JSON string (populated from a database, google sheet, or other webservice) and populates a radio control with matching options. The form has a hidden textarea control, used to save and reuse the JSON string. It also has a text control, trigger, radio control and error message.
- Write a rule to fetch the data from your system and store it in the textarea, as described here.
Write the following rule to search the stored JSON string and populate the radio control. This rule uses the conditions of a value change in the custName text control OR a trigger click; you only need to choose one of those conditions.
/*member customers, id*/ var string; var customerlist = JSON.parse(CustomerListJson.value.trim()); if (custName.value.length > 0 || onClick.clicked){ var matchingcustomers = []; var matchtext = custName.value.toLowerCase(); for (var i=0; i<customerlist.customers.length; i++){ if (customerlist.customers[i].name.toLowerCase().indexOf(matchtext) >= 0){ matchingcustomers.push(customerlist.customers[i].id + '=' + customerlist.customers[i].name); } } if (matchingcustomers.length > 0){ SelectCustomer.visible = true; SelectCustomer.printable = true; SelectCustomer.options = matchingcustomers; noMatches.visible = false; } else { noMatches.visible = true; SelectCustomer.visible = false; SelectCustomer.printable = false; } } else { noMatches.visible = false; SelectCustomer.visible = false; SelectCustomer.printable = false; }
The result is a handy search form:
Value Change & Dynamic Options
This rule dynamically sets the options in a dropdown list based on the value selected in another form field. This form contains three fields named Products, Series and Model. The series options are set dynamically based on the product selection. Also when a new product is selected we enable the series dropdown and both clear and disable the model dropdown. This form contains other rules which set the models based on the selected series.
if (product.value === 'Laserjet Printers') { series.options = [' ', 'Laserjet5 series', 'Laserjet6 series']; series.enabled = true; model.options = []; model.enabled = false; }
Dynamic Control Initialization using JSON
This rule handles the case of initializing multiple control values based on the selection of a dropdown control. It handles this case better than using a long if/else construct by using a JSON string. First add options to the dropdown named SalesRep in the format <value>=<label> where <value> will be used as an index key into a JSON array of details about each person.
Megan=Megan Smith Jim=Jim Brown Nancy=Nancy Jones Brian=Brian Jones
Then write a rule that first sets up a javascript JSON syntax array with the contact information for each person. The rules then uses the dropdown value to index into the contactInfo array to set the details for the selected person into four other form controls.
/*member '' Brian Jim Megan Nancy cell email phone */ var contactInfo = { "" : { name : "", email : "", phone : "", cell : "" }, "Megan" : { name : "Megan Smith", email : MSmith@mycompany.com, phone : "(203) 694-2439 Ext. 516", cell : "(203) 337-3242" }, "Jim" : { name : "Jim Brown", email : jim@comcast.net, phone : "203-208-2999", cell : "" }, "Nancy" : { name : "Nancy Jones", email : nancy@snet.net, phone : "203-208-2991", cell : "" }, "Brian" : { name : "Brian Jones", email : BJones@mycompany.com, phone : "203-748-6502", cell : "" } }; var repId = SalesRep.value; SalesRepName.value = contactInfo[repId].name; SalesRepEmail.value = contactInfo[repId].email; SalesRepPhone.value = contactInfo[repId].phone; SalesRepCell.value = contactInfo[repId].cell;
Try this simple Clinic Location form which uses this approach to initialize its controls.
Signatures
The following examples demonstrate rules working with wet and digital signatures.
Digital Signature
This form uses a rule to pass a username and password to a LDAP Active Directory authentication service. If authentication fails the form makes an error message control visible. If authentication succeeds the form disables the username form field and replaces the password field with a date field set to the current date. The form contains a trigger control named sign, username and password fields named u and p respectively, a date field named d and a message field named m.