Execute JavaScript from rules: Difference between revisions
Appearance
→Additional information: min version |
|||
| (7 intermediate revisions by 2 users not shown) | |||
| Line 21: | Line 21: | ||
# Create a new variable and use the [[Rules_editor#Operations|operation '''ExecuteJS''']]. | # Create a new variable and use the [[Rules_editor#Operations|operation '''ExecuteJS''']]. | ||
[[File:Sample executejs rule.png|600px]] | [[File:Sample executejs rule.png|alt=Execute JavaScript from rules: Add function call to form rules|600px]] | ||
== Additional information == | == Additional information == | ||
| Line 27: | Line 27: | ||
* The operator ExecuteJS is supported only for variables of the following types: Boolean, String, Integer, Double, Float, Decimal, Money, DateTime, StringList, Entity, Lookup. | * The operator ExecuteJS is supported only for variables of the following types: Boolean, String, Integer, Double, Float, Decimal, Money, DateTime, StringList, Entity, Lookup. | ||
* In the first argument, select the IFrame form tab that links to the script. In the second argument, enter the name of the JavaScript function. | * In the first argument, select the IFrame form tab that links to the script. In the second argument, enter the name of the JavaScript function. | ||
* The serialized MobileCRM.UI.EntityForm object is automatically passed as a parameter to the function. You cannot pass a custom input parameter. | * The serialized MobileCRM.UI.EntityForm object is automatically passed as a parameter to the function. | ||
** You cannot pass a custom input parameter. | |||
** You can read from the EntityForm but you cannot update the fields. If you need to update the properties of the entity record, you need to request the entity form again in the scope of Execute JS function. | |||
* The implementation supports also ''promises'' for asynchronous result return from functions. | * The implementation supports also ''promises'' for asynchronous result return from functions. | ||
* ExecuteJS requires offline HTML running JSBridge.js script version 13.1 or later. | * ExecuteJS requires offline HTML running JSBridge.js script version 13.1 or later. | ||
| Line 38: | Line 40: | ||
* In the first argument, simply select the value "IFrame". (Questionnaires don't have multiple tabs for selecting.) | * In the first argument, simply select the value "IFrame". (Questionnaires don't have multiple tabs for selecting.) | ||
[[File:Execute javascript in questionnaire rules.png|600px]] | [[File:Execute javascript in questionnaire rules.png|alt=Execute JavaScript from rules: Execute javascript in questionnaire rules. example|600px]] | ||
See also: | |||
* [[Resco_JavaScript_Bridge#Questionnaire|General instructions about JavaScript in questionnaires]] | |||
* [[Deep dive: Aggregate questions in repeating groups]] | |||
== Example == | == Example == | ||
| Line 57: | Line 63: | ||
var account = new MobileCRM.FetchXml.Entity("account"); // NOTE: If we save to shared variable of type entity ACCOUNT, we need to create/fetch account entity. | var account = new MobileCRM.FetchXml.Entity("account"); // NOTE: If we save to shared variable of type entity ACCOUNT, we need to create/fetch account entity. | ||
account.addAttributes(); | account.addAttributes(); | ||
var fetch = new MobileCRM.FetchXml.Fetch(account); | var fetch = new MobileCRM.FetchXml.Fetch(account); | ||
| Line 68: | Line 72: | ||
}); | }); | ||
} | } | ||
function getContactEntity() { | function getContactEntity() { | ||
| Line 75: | Line 77: | ||
var contact = new MobileCRM.FetchXml.Entity("contact"); // NOTE: If we save to shared variable of type entity ACCOUNT, we need to create/fetch account entity. | var contact = new MobileCRM.FetchXml.Entity("contact"); // NOTE: If we save to shared variable of type entity ACCOUNT, we need to create/fetch account entity. | ||
contact.addAttributes(); | contact.addAttributes(); | ||
var fetch = new MobileCRM.FetchXml.Fetch(contact); | var fetch = new MobileCRM.FetchXml.Fetch(contact); | ||
fetch.execute("DynamicEntities", function (res) { | fetch.execute("DynamicEntities", function (res) { | ||
var current = res[getRandomInt(res.length)]; | var current = res[getRandomInt(res.length)]; | ||
var entity = new MobileCRM.DynamicEntity(current.entityName, current.id, current.primaryName, clearInvalidProps(current.properties)); | var entity = new MobileCRM.DynamicEntity(current.entityName, current.id, current.primaryName, clearInvalidProps(current.properties)); | ||
| Line 90: | Line 87: | ||
}); | }); | ||
} | } | ||
function getLookUp() { | function getLookUp() { | ||
| Line 103: | Line 92: | ||
var contact = new MobileCRM.FetchXml.Entity("contact"); | var contact = new MobileCRM.FetchXml.Entity("contact"); | ||
contact.addAttributes(); | contact.addAttributes(); | ||
var fetch = new MobileCRM.FetchXml.Fetch(contact); | var fetch = new MobileCRM.FetchXml.Fetch(contact); | ||
| Line 113: | Line 100: | ||
}); | }); | ||
} | } | ||
function getInteger() { return getRandomInt(128); } | function getInteger() { return getRandomInt(128); } | ||
| Line 126: | Line 111: | ||
for (var i = 0; i < getRandomInt(); i++) | for (var i = 0; i < getRandomInt(); i++) | ||
res.push(getRandomString()); | res.push(getRandomString()); | ||
return res; | return res; | ||
| Line 136: | Line 119: | ||
} | } | ||
// **** Helpers **** | // **** Helpers **** | ||
function getRandomString(length) { | function getRandomString(length) { | ||
| Line 154: | Line 134: | ||
</html></syntaxhighlight> | </html></syntaxhighlight> | ||
[[Category: | |||
{{Feedback}} | |||
[[Category:Business logic]] | |||
Latest revision as of 11:55, 24 April 2025
The Resco platform offers two main options for adding client-side business logic to your projects:
- Rules which represent the no-code approach for simpler use cases
- Resco JavaScript Bridge that allows you to write custom scripts to modify UI, data, and access additional functions
The option to execute scripts directly from rules combines these two options. It aims to simplify writing JavaScript for Mobile CRM by removing the need for boilerplate code, and it should open a path for creating reusable JavaScript libraries with additional functionality for Resco mobile apps, e.g., additional math, date, or string operations, and also business logic.
| Warning | For now, this option is supported for form rules and questionnaires. Do not attempt to use the ExecuteJS function in other rules, for example, in views. |
Offline HTML
In the Offline HTML section of Woodford, you need to add the following:
- JSBridge.js (the file provided by Resco that contains the method to execute JS desired function from Woodford rule editor)
- An HTML file with scripts. An example of such a script is available below.
Add function call to form rules
- Edit a form in Woodford.
- Click Add IFrame and link to the file script that you uploaded to the offline HTML folder in the previous section.
- Next, open the rules editor for an event, for example, On Save.
- Create a new variable and use the operation ExecuteJS.
Additional information
- The operator ExecuteJS is supported only for variables of the following types: Boolean, String, Integer, Double, Float, Decimal, Money, DateTime, StringList, Entity, Lookup.
- In the first argument, select the IFrame form tab that links to the script. In the second argument, enter the name of the JavaScript function.
- The serialized MobileCRM.UI.EntityForm object is automatically passed as a parameter to the function.
- You cannot pass a custom input parameter.
- You can read from the EntityForm but you cannot update the fields. If you need to update the properties of the entity record, you need to request the entity form again in the scope of Execute JS function.
- The implementation supports also promises for asynchronous result return from functions.
- ExecuteJS requires offline HTML running JSBridge.js script version 13.1 or later.
- Release 14.2 change: Before this release, values returned from JSBridge were wrapped in an extra set of quotation marks (for example,
"123"for numbers or""text""for strings). After the release, one pair of quotation marks is gone (123,"text"). If you're switching from an older version of JSBridge.js, please update your scripts.
Questionnaire specifics
The behavior of the ExecuteJS operator in questionnaire rules is similar to forms:
- It is supported for variables and also whenever you can enter a value; for example for Question.Value.
- In the first argument, simply select the value "IFrame". (Questionnaires don't have multiple tabs for selecting.)
See also:
- General instructions about JavaScript in questionnaires
- Deep dive: Aggregate questions in repeating groups
Example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JS from Resco rules</title>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta name='viewport' content='initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'>
<script type='text/javascript' src='JSBridge.js'></script>
</head>
<body>
<script>
function getAccountEntity() {
return new Promise(function(resolve, reject) {
var account = new MobileCRM.FetchXml.Entity("account"); // NOTE: If we save to shared variable of type entity ACCOUNT, we need to create/fetch account entity.
account.addAttributes();
var fetch = new MobileCRM.FetchXml.Fetch(account);
fetch.execute("DynamicEntities", function (res) {
var current = res[getRandomInt(res.length)];
var entity = new MobileCRM.DynamicEntity(current.entityName, current.id, current.primaryName, clearInvalidProps(current.properties));
resolve(entity);
}, reject, null);
});
}
function getContactEntity() {
return new Promise(function (resolve, reject) {
var contact = new MobileCRM.FetchXml.Entity("contact"); // NOTE: If we save to shared variable of type entity ACCOUNT, we need to create/fetch account entity.
contact.addAttributes();
var fetch = new MobileCRM.FetchXml.Fetch(contact);
fetch.execute("DynamicEntities", function (res) {
var current = res[getRandomInt(res.length)];
var entity = new MobileCRM.DynamicEntity(current.entityName, current.id, current.primaryName, clearInvalidProps(current.properties));
resolve(entity);
}, reject, null);
});
}
function getLookUp() {
return new Promise(function(resolve, reject) {
var contact = new MobileCRM.FetchXml.Entity("contact");
contact.addAttributes();
var fetch = new MobileCRM.FetchXml.Fetch(contact);
fetch.execute("DynamicEntities", function (res) {
var current = res[getRandomInt(res.length)];
resolve(new MobileCRM.Reference(current.entityName, current.id, current.primaryName));
}, reject, null);
});
}
function getInteger() { return getRandomInt(128); }
function getString() { return getRandomString(); }
function getDecimal() {
var precision = 100; // 2 decimals
return Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1 * precision);
}
function getStringList() {
var res = [];
for (var i = 0; i < getRandomInt(); i++)
res.push(getRandomString());
return res;
}
function getDateTime() {
var dt = new Date();
return dt.toLocaleTimeString();
}
// **** Helpers ****
function getRandomString(length) {
var len = length || 7;
return Math.random().toString(36).substring(len);
}
function getRandomInt(maximum) {
var max = maximum || 4;
return Math.floor(Math.random() * Math.floor(max));
}
</script>
</body>
</html>
{{#CI form: title = Was this information helpful? How can we improve?
| type = inputs
| [textarea]
}}