Build your first customisation
Less than to read
Now we understand how to customise web screens, work with the schema and how to deploy extensions, lets start building a new customisation.
In this walkthrough we’ll look to add a new textbox to the new and amend supplier screens, that allows us to add a nick name to each supplier. We will store the data in the spare_text_1
field of each supplier object.
Navigate to the Web extensions screen, and click Add
.
We are presented with a new schema template:
{
"version": "1.0",
"pages": [],
"uiExtensions": [],
"actions": {},
"validations": {},
"events": []
}
At this stage we don’t need to change the version so leaving it at 1.0 is fine.
Next we will select the pages we want the customisations to appear on.
Pages
As we want this customisation to appear on both the new and amend supplier screens, we need to add the identifiers from the page url for each:
{
...
"pages": [
"purchase/new-supplier",
"purchase/amend-supplier"
],
...
}
Now to add the text box component.
UI Extensions
Using the UI Extesnions section we can define our textbox component. We will give it an id, of Nickname
and specify the component type of Textbox, and bind it to spare_text_1
on the supplier object. Specifying a label
will add a label next to the textbox keeping the component in the same style as the rest on the screen.
In its default/initial state we would like the textbox to be disabled
, so that it matches the default behaviour on the amend-supplier
page, so we set its property to true
. Finally we add mt
which is shorthand for margin-top
to 2 pixels, which keeps the spacing around the component consistent.
"uiExtensions": [
{
"id": "Nickname",
"component": [
{
"Textbox": {
"id": "spare_text_1",
"label": "Nickname",
"disabled" : true,
"mt": 2
}
}
]
}
],
We will define this components position in the events section.
Events
The events section will allow us to subscribe to the onLoad event of the screen.
onLoad
We can use the onLoad event to add our UIextension
component (spare_text_1
). We can do this by choosing an existing component on the screen, and placing our extension above, below or to either side of it:
"events": [
{
"onLoad": [
{
"set": {
"pageExtension": {
"componentId": "short_name",
"panel": "bottom",
"uiExtension": "Nickname"
}
}
}
]
}
]
Here we are setting up a pageExtension
, to extend a component at the page level (as opposed to a componentExtension
, where you are adding a child component inside another component e.g. a grid to a pod), and specifying the id of another component next to where we want our new one to be placed.
In this case we use the short_name
text box, and add it to the same panel at the bottom, so underneath. We specify which component to add here using the uiExtension
property.
There is an issue however, we have set the text box to disabled so that its the same as other components on the amend-supplier
screen, but what about the new-supplier
screen?
Current appearance of the New Supplier screen:
An disabled text field on a new supplier screen
Lets now look at setting up an action to enable the component.
Actions
In order to enable the component, we can simply create an action:
"actions": {
"enableField": [
{
"set": {
"properties": {
"spare_text_1": {
"disabled": false
}
}
}
}
]
},
In the above example, we have created an action called enableField, which simply sets the disabled
property of the text field component (spare_text_1
) to false.
We can then call this action in an event such as onLoad when we open a screen such as new-supplier
.
Calling actions
We can now add to our existing onLoad
event to make a second call, specifically for a given screen, in this case the purchase/new-supplier
. We do this by adding a new pages
section inside a new event object, and then hooking into the onLoad event again calling the action we created, enableField
:
"events": [
{
"onLoad": [
{
"set": {
"pageExtension": {
"componentId": "short_name",
"panel": "bottom",
"uiExtension": "Nickname"
}
}
}
]
},
{
"pages":[
"purchase/new-supplier"
],
"onLoad":[
{
"action": "enableField"
}
]
}
]
The first event object in the array adds and positions the uiExtension, and the second defines the page, and event we want to hook into.
We specify on the purchase/new-supplier
screen, during the onLoad
event we will fire the action enableField
which we specified earlier.
When we load the screen, we now see the field enabled, and consistent with the existing component behaviour:
An enabled text field on a new supplier screen
Validations
We should also look at adding some validation to the new component we’ve added. In this case lets prevent the user from adding a nickname more than 10 characters long.
We can achieve this by setting a constraint on the maximum number of characters you can pass into the text box:
"validations": {
"errors": [
{
"field": "spare_text_1",
"type": "string",
"constraints": {
"max": {
"value": 10,
"message": "Max 10 characters!"
}
}
}
]
},
Now if you try to add a nickname thats longer than 10 characters an error is shown to the user:
One final issue we still have, is that if we go to the purchase/amend-supplier
screen, and choose a supplier, our nickname field is still not enabled. Let’s now look at how we can fix that.
onStateChange
We can do this by returning to our events
section, and this time hooking into the onStateChange event. This allows us to monitor for changes in the state a component.
Our events section now should look like this:
"events": [
{
"onLoad": [
{
"set": {
"pageExtension": {
"componentId": "short_name",
"panel": "bottom",
"uiExtension": "Nickname"
}
}
}
]
},
{
"pages": [
"purchase/new-supplier"
],
"onLoad": [
{
"action": "enableField"
}
]
},
{
"pages": [
"purchase/amend-supplier"
],
"onStateChange": [
{
"watchTarget": "name",
"onChange": [
{
"if": {
"ne": [
{
"get": {
"state": "name"
}
},
{
"string": {
"value": ""
}
}
],
"then": [
{
"action": "enableField"
}
],
"else": [
{
"set": {
"properties": {
"spare_text_1": {
"disabled": true
}
}
}
}
]
}
}
]
}
]
}
In the above example, we hook into the onStateChange
event, and set a watchTarget
by specifing an element on the screen, in this case the supplier name
. We then state that when the name changes using the onChange
event, if the name is not equal (ne
) to a blank string (“”), then call the action enableField
like we did earlier on the new-supplier screen, if not else
disable the field.
This means that when the amend-supplier
page loads, the field will be disabled until a supplier has been selected, the name updates and the field enables.
This then corrects the issue and on the amend-supplier
screen once a supplier has been selected, the component activates like the default ones.
Congratulations! You now have a working web extension that adds a textbox to multiple screens, writes back to the database using the a spare text field, utilising events, and even includes validation.
Feel free to download a copy of the fully completed schema file used in the example.
Next - Next steps