How to use script includes in UI Builder
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-20-2023 12:05 AM
Recently I wanted to use a script include in UIB. To my surprise, I was not able to find any instruction of how to do it. After some time, I have figured it out but it was not a trivial thing. Hence, I decided to share a basic guide for those who, similarly to me, struggle with the lack of information on this topic.
My post will have three parts:
- Basic information about script includes in UIB
- Backend part: How to create a definition of a new script include
- Frontend part: How to call the script include in a UIB script
In the post, I will be using these shortcuts:
- UIB = UI Builder
- SI = script include
- ES = EcmaScript
- FE = frontend
1) Basics about the UIB script includes
The UIB SIs are different from the standard SIs:
- the latter ones run server side, whereas the former ones only run client side.
This means that:
- UIB SIs are stored in their own, separate table: [sys_ux_client_script_include]
- you are not able to call server side APIs in UIB SIs (such as GlideRecord etc.)
- on the other hand, since the UIB SIs run in your browser, you are not restricted to ES5 in them (in other words, you are free use the arrow functions, "let" and "const" keywords etc.)
2) Backend part: How to create a new SI definition
In the UX Client Script Includes table [sys_ux_client_script_include], create a new record.
The form will be looking like this:
You might wonder what is the difference between Name and API Name fields:
- Name = the "display name" of your script
- on the FE side, you will use it to add the SI into a UIB script
- API Name = the "system name" of your script
- on the FE side, you will use it to call the SI in the UIB script
- API Name is read-only field and will auto-populate
- the value consists of two dot-separated parts:
- the first one = your current application scope
- the second one = the value you have put into the Name field
- so, if you are in the global scope and the Name is "exampleSI", the API Name would be: global.exampleSI
However, the most important field is the Script field. You can see a prefilled include function there, looking like this: function include({imports}){}. Here is where all the magic happens. Whatever you put in the empty curly brackets will be executed in your browser after you call the SI.
For example, let´s say you have a SI like this:
function include({imports}){
console.log("Hello world");
return "The script was called";
}
After calling it, this SI will log "Hello world" to your browser console, while returning another string ("The script was called") that can be further used in the script in which the SI is called.
Of course, usually we do not want the SIs just to return some hard-coded value. Usually, we want the SI to return a value based on an input. So how can we do THAT?
Well, this is the tricky part. In order to be able to pass any input values to the SI, we need to define a function WITHIN the include function and return that inner function.
I will explain it on an example. For the sake of simplicity, let´s assume we want a SI that will work like this: it will take two numbers as arguments and it will return their sum.
Such a SI could look like this:
function include({imports}){
return addTwoNumbers;
function addTwoNumbers(num1, num2) {
return num1 + num2;
}
}
As you can see, the core of the SI is still the include function as it was in the previous example. Only now the include function is somewhat more complex: it returns the addTwoNumbers function which, on its part, returns the sum of its two arguments.
The complete definition of our SI could look something like this:
For our purposes, we have allowed this script to be called from any application scope, but you can restrict it to your scope only (using Accessible from field).
Now we have our SI defined and we can call it from the FE.
3) Frontend part: How to call the SI in a UIB script
Let´s assume that in the UIB we have already created a page and on that page we have a script called exampleFrontendScript (which is triggered, for example, by clicking a button).
Now, inside this exampleFrontendScript we want to call our exampleSI, so we would pass it two numbers and receive their sum.
In order to achieve that, you need to do two things:
- add the SI to your script
- call the SI in your script
Step 1: adding the SI
- open your UIB script
- in our case: exampleFrontendScript
- in Details section, click on Script includes
- click on Add a script include field and choose the SI you want to use
- in our case: exampleSI
- the scripts are displayed by their names
- i.e. by the value of the Name field in the SI definition
- after choosing the SI, click on Add button (don´t forget this, otherwise the SI won´t work!)
- now the SI should have been added and the Details section should look like this:
Step 2: calling the SI
- to call the SI in your script, use this formula:
- imports['<API Name of the SI>']()(args)
- in our case: imports['global.exampleSI']()(num1, num2)
- in other words:
- we call the SI by using its API Name
- i.e. the value from the API Name field in the SI definition
- the API Name is a string and it is inside square brackets
- the square brackets are followed by round brackets in order to call the include function
- the round brackets are followed by another round brackets in order to call the addTwoNumbers function and pass it the arguments
- in our example, the logic behind the formula works like this:
- imports['global.exampleSI']
- this would return the include function (without calling it)
- as a result, we would receive the object of the include function
- imports['global.exampleSI']()
- this would return include function AND call it
- since the include function itself returns the addTwoNumbers function, this would return the addTwoNumbers function (without calling it)
- as a result, we would receive the object of the addTwoNumbers function
- imports['global.exampleSI']()(1, 2)
- this calls the addTwoNumbers function, passing it two arguments (1, 2)
- as a result, we receive the sum of the arguments => 3
So, the whole exampleFrontendScript can look something like this:
function exampleFrontendScript({api, event, helpers, imports}) {
let num1 = 1,
num2 = 2,
valueFromSI = imports['global.exampleSI']()(num1,num2);
console.log(`${num1} + ${num2} = ${valueFromSI}`);
}
I hope this post was useful. Any remarks, suggestions or further thoughts would be appreciated as I am by no means any expert on this topic.
- 14,207 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-28-2024 06:41 AM
Hi,
Thanks for the response.
I need the saved values to be persisted each time the portal page is refreshed. I don't believe the client state parameters allow this so maybe I need to store data in a custom table?
Regards,
Kristian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-28-2024 09:25 PM
Hi, Kristian,
you are right, client state parameters are not meant to store "permanent" data. But UIB allows you to communicate with your backend, including your tables. Hence, you can store your data there and/or fetch it from there. This can be done using data resources.
Also, you can make REST API calls from UIB scripts which allows you to leverage scripted REST APIs and call them from your UIB script to execute any backend operation, including CRUD operations over your tables to store/fetch data.
So hopefully, one of those will help you.
Honza
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-29-2024 04:35 AM
Hi Honza,
Thank you for sharing this, it is most helpful.
I will look to use Data resources and rest requests to save and retrieve my data from a custom table.
Regards,
Kristian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-29-2024 08:04 AM
I solve my issue using a custom table and making a rest call to put data in it from the UIB script.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-29-2024 09:59 PM
Perfect, very glad to hear that, Kristian! 🙂