How to add records in a related list with UI builder (declarative action)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-15-2023 02:41 AM - edited 09-05-2024 12:27 AM
Hi all!
This guide was mainly made for Utah and Vancouver release, it may not work the same way in future releases. Hopefully ServiceNow makes it easier to accomplish this.
Introduction to declarative actions
I will not dwell into how declarative actions work and the nitty gritty side of it, therefore I urge you to read Ashley Snyder's guide on declarative actions as it was very helpful! But it seems like how the OOTB record page template is setup after Utah is different than how it is in the Service operations workspace(SoW), so I could not get my "Add" button to work outside of SoW which is my requirment due to me having a custom built workspace. So I had to find another way for the button to work like Ashley's, this is what I am going to show you in this article.
Creating the button
This is pretty much the same as how Ashley does it in her guide, since we are creating it for a related list go to: Workspace Experience > Actions & Components > Related List Actions and hit "new".
Implement it as a UXF Client Action. Give it a label (what the button name will be) and a distinct action name. Choose the table the button will show up in, now we will create the client action. We will make it generic so we can re-use the client action in other places, by doing this we only need to specify the payload mappings for the different action assigments instead of having to create multiple client actions.
Give the action a key that's unique and it has to be written in the same way as mine. Give it a label, since I said you should make it generic call it something like "Re-usable ADD button for UI builder". Select related list under applicable to and then add this to the payload:
{
"label": "{{label}}",
"userGivenTable": "{{userGivenTable}}",
"table": "{{table}}",
"parentRecordSysId": "{{parentRecordSysId}}",
"relatedListName": "{{relatedListName}}",
"hideSelectAll": "{{hideSelectAll}}",
"parentFieldName": "{{parentFieldName}}",
"referencedFieldName": "{{referencedFieldName}}",
"extensionPoint": "{{extensionPoint}}",
"view": "{{view}}",
"columns": "{{columns}}",
"type": "{{type}}"
}
Hit save and the action payload mapping and fields in the related list on the record will be automatically populated.
Define the mappings from the payload
You can now specify the values as I stated earlier. Go back to the action assignment, select advanced view from the related links choose the action attributes section and fill in values in the payload map.
"userGivenTable" is the table you want to pick records from. For further explanation of the other fields please see this docs from ServiceNow. Do not fill in fields you do not use/need. For instance I am not using a specific view nor an extension point these are therefore not filled out along with some others. Hit save.
You can now see the button on the related list(table) you specified in the action assignment record but it does nothing when you click on it. You have to create a UX Add-on event mapping which will trigger an event.
Create the UX add-on event mapping
This is where it really differs from the other guides on how to create the "Add" button. As I stated in the beginning the SoW record page that's used in these guides is setup differently than in a custom workspace along with the related list component in the UI builder, I think these changes came in Utah but I am not certain. We will not be using the Parent macroponent and Source element ID. The UI Controller Page under Controller holds the [Record Page] Open Modal event we need. The source component should be List - Related as this is the component that's used in the Record page now, also be sure to select your action assignment in the Source Declarative Action field.
In Utah you need to alter the reference qualifier on the Target event field, configure dictionary and add this to the reference qual:
javascript;'sys_idIN' + current.parent_macroponent.handled_events + '^ORsys_idIN' + current.controller.controller_macroponent.handled_events
This will make you able to select events from the UI Controller Page.
Add this to the target payload mapping:
{
"container": {
"fields": {
"container": {
"columns": {
"binding": {
"address": [
"columns"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"extensionPoint": {
"binding": {
"address": [
"extensionPoint"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"hideSelectAll": {
"binding": {
"address": [
"hideSelectAll"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"label": {
"binding": {
"address": [
"label"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"parentFieldName": {
"binding": {
"address": [
"parentFieldName"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"parentRecordSysId": {
"binding": {
"address": [
"parentRecordSysId"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"referencedFieldName": {
"binding": {
"address": [
"referencedFieldName"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"relatedListName": {
"binding": {
"address": [
"relatedListName"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"table": {
"binding": {
"address": [
"table"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"userGivenTable": {
"binding": {
"address": [
"userGivenTable"
]
},
"type": "EVENT_PAYLOAD_BINDING"
},
"view": {
"binding": {
"address": [
"view"
]
},
"type": "EVENT_PAYLOAD_BINDING"
}
},
"type": "MAP_CONTAINER"
},
"params": {
"container": {
"type": {
"binding": {
"address": [
"type"
]
},
"type": "EVENT_PAYLOAD_BINDING"
}
},
"type": "MAP_CONTAINER"
},
"route": {
"type": "JSON_LITERAL",
"value": "mra"
},
"size": {
"type": "JSON_LITERAL",
"value": "lg"
}
},
"type": "MAP_CONTAINER"
}
Now save and clear your cache (cache.do), for some reason this never works without clearing the cache. Go to your related list, hit the "Add" button and the modal should now open and let you select records (one last step for Utah)!
UX App Route
For Utah you need one more step to get the modal to open up. You need to create a UX app route(sys_ux_app_route.list) for the page where the modal is going to open.
Here the parent macroponent is the page you would have used in the older guides that are based on SoW. Element ID should be modalContainerViewport which is the modal component on the new record pages. Finally add the fields (which are the same fields that you have already worked with earlier):
userGivenTable,table,label,parentRecordSysId,parentFieldName,referencedFieldName,extensionPoint,view,columns,hideSelectAll,type,relatedListName
This record tells your page what to do with MRA routings. Seems like the work for it to happen automatically is done in Vancouver but not in Utah. Now your button should work as intentended in Utah aswell!
Client conditions
In your action assignments select the advanced view and then the conditions section, what I did is tell it to only show under the related list with the label name "Action Cards" and require write access on the table. You can play around with the different conditions to suit your needs. You could also experience restrict your action and make use of Dynamic evaluation!
- Labels:
-
UI Builder : Next Experience
- 6,522 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-15-2025 12:22 AM
Hi @Benjamin JS ,
How did you trigger the page refresh? Did you use g_list.refresh() in a client script or is it in UI Builder?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-15-2025 01:01 AM
Hello @frviuf it's not actually a page refresh per se. It's been a while since I configured this but I think within the confirm button of the modal I added a data resource refresh.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-17-2025 01:49 PM
Thank you for the reply!
Here is what worked for me:
1. Open your workspace record page in UI Builder.
2. Create a client state parameter named refreshList - Type: JSON - Initial Value: {}
3. Create a client script named refreshListView. Script:
function handler({api, event, helpers, imports}) {
api.setState('refreshList', {
timestamp: Date.now()
});
}
4. In the UI Builder sidebar, go to Modals and select Modal Container (Viewport).
5. Under Modal closed - select add event handler - under Scripts, choose refreshListView.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-22-2025 12:19 AM
Yes, that works aswell
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-18-2024 08:59 AM
Hi @Benjamin JS , I figured it out. I was missing the parentFieldName in the payload map. Thanks!
Regards,
Randi