MaestroThe UI design product. | Form Builder | 23.04This feature was updated in 23.04
Maestro allows you to add business rules to components used in a form.
A business rule is a JavaScriptJavascript (JS) is a scripting languages, primarily used on the Web. It is used to enhance HTML pages and is commonly found embedded in HTML code. JavaScript is an interpreted language. Thus, it doesn't need to be compiled. function that is invoked in response to different events related to a component. Developers working in Maestro do not normally see the function scaffold that is provided by the platform, but it is important that developers understand how this works.
Rules are invoked by the Maestro framework in response to:
For example, a Valid If rule is triggered when the data value changes, a Click rule when the user clicks on an element, a Page Load rule every time a Maestro page is shown, and so on.
Rule developers need to understand what is provided by Maestro in the scope of a rule function:
argument[0]
) to the JavaScript rule function.argument[1]
) to the JavaScript rule function.getData()
and setData()
methods.argument[2]
) to the JavaScript rule function.applicant_firstName
, the value variable would be created by the framework as follows:
var value = data.applicant_firstName;
Calc.total( data.expenses, "expense" )
expense
properties stored in the expenses
array. In addition to this, the API exposes some methods on the global scope.The Maestro’s Create Rule dialog lists the available rules for the selected item:
For more information, see List of Maestro Rules.
You can also create your own business rule types and add them to the Create Rule dialog, and so expose them via the Properties pane. However, these rule types must be for native components only as described in Component Options.
You can only add one rule of each type to a component.
Some components can't have rules added to them, so you won't see the Rules category or any rules displayed in the Properties pane. These components include:
The Rule editor is designed to be as simple as possible to use, but sometimes, this leads to unexpected side effects.
Consider a developer who is writing a Calculation rule on a Data Field and needs to inspect the current value and type of the object:
console.info("Value: " + value);
console.info("Value type: " + typeof value);
The console output is:
value: 12
What happened to the second console statement? Why wasn’t it output?
Maestro does not see a return statement and so ‘helpfully’ adds it to the first line of the script. If you were to code this yourself, you would write the following – with the warning because the second line is unreachable:
return console.info("Value: " + value);
console.info("Value type: " + typeof value);
The lesson is that if you write a muti-line rule that defines local variables and expects a return value, you must provide a return statement:
console.info("Value: " + value);
console.info("Value type: " + typeof value);
return value;
When you are developing rules, test your work often in the debugger. Several types of errors, for example compilation problems, can result in your form not displaying correctly in Preview mode.
The earlier you test, the more likely you are to find the bit of code that is causing the problem.
Maestro rules are JavaScript and, whereas Maestro hides much of the complexity, rule developers should have a foundation in the language. We recommend the Mozilla Developer Network first steps course.
All data is stored in Strings which can lead to unexpected results. Consider this rule snippet:
console.info("Value: " + value);
console.info("Item.getData() type: " + typeof item.getData());
console.info("data.income type: " + typeof data.income);
console.info("Value type: " + typeof value);
data.income = 678.90;
console.info("Value set to 678.90");
console.info("Item.getData() type: " + typeof item.getData());
console.info("data.income type: " + typeof data.income);
Running this rule results in the following output in the browser, with the income in the form field displayed above the developer tools console:
Let's break down what’s going on here:
123.45
, which was the data entered by the user that led to the rule being triggered.item.getData()
returns the data.income
property and this is also assigned to the value property – all have a type of string
.This demonstrates that data input into a form is stored as string
type by the Maestro framework in the data model.
data.income = 678.90
. The type of the right hand side of this expression is a JavaScript number. (This could also have been achieved by using a function call: item.setData(678.90)
.)item.getData()
and data.income
show that the updated value in the data model has a type of number
.This demonstrates that data input into the data model in a script is stored in the type given.
It should be clear from the above, that rule developers should take care with assumptions about the types they are working with.
If a user inputs a numeric value in an income field and Maestro stores this as a string
, how do developers do math?
If we used the data.income
property in an expression, you would see an unexpected result. Consider an expression that assumed two numeric values:
console.info("data.income value: " + data.income);
console.info("data.income type: " + typeof data.income);
console.info("data.frequency value: " + data.frequency);
console.info("data.frequency type: " + typeof data.frequency);
let yearlyIncome = data.income * data.frequency;
console.info("Income: " + yearlyIncome);
The console shows the result:
data.income value: 1234
data.income type: string
data.frequency value: "1"
data.frequency type: string
Income: NaN
Two strings can't be multiplied, hence the result NaN (Not a Number).
There is no magic here – rule developers must learn about JavaScript type coercion, which is the automatic or implicit conversion of values from one data type to another, such as strings to numbers.
To coerce a string
to a number
, simply prefix the data value with a +
, as shown below:
console.info("data.income value: " + (+data.income));
console.info("data.income type: " + typeof (+data.income));
console.info("data.frequency value: " + (+data.frequency));
console.info("data.frequency type: " + typeof (+data.frequency));
let yearlyIncome = +data.income * +data.frequency;
console.info("Income: " + yearlyIncome);
This gives you the result you expect:
data.income value: 1234
data.income type: number
data.frequency value: 12
data.frequency type: number
Income: 14808
Because rule developers can add any type into the data model, to ensure expected behavior, we recommend that developers performing calculations should always use type coercion.
To force the conversion of any value to a boolean
, developers can use a double negation (or double not), namely, !!
.
This is a standard JavaScript technique that relies on "truthyness" or "falsyness" of the value. The first !
converts a ‘truthy’ value to false and a ‘falsy’ value to true. The second !
flips these.
This technique is commonly used to check whether an element exists.
Consider the case where an application allows single and joint applicants for a product. A form design may wish to only show a text display field when both applicant’s details are known.
To handle this, we would create a Visibility Rule using the technique we just learned:
!!data.applicant1_name && !!data.applicant2_name
If you have, for example, some values in a dropdown list, and want to turn these into more human readable values, you could use an if statement or a switch statement. However, if you want to embed the logic inside some text, you can use the following object key lookup syntax:
{{ {'52': 'per week', '24': 'bi-monthly', '12': 'per month'} [data.frequency] }}
This defines an object with keys 52
, 24
, and 12
and then looks up the key matching the data field [data.frequency]
which, in turn, returns a human readable string
describing the value. For more information, see Introduction to Maestro Business Rules.
If you are experiencing some issues with business rules, learn how to debug them.
Next, learn how to create a rule.