Arnoud Kooi
ServiceNow Employee
ServiceNow Employee

This is a practical walkthrough, of how to create a button on a Workspace Experience Record.
In real world, be sure to create the artifacts in the appropriate scope.
Please note this is based on my experience and this article is not part of what the COE team publishes.

Video

I recommend you watch the video. If you watch it on YouTube, you can use the time markers.
Also, take good notice of the guidance and remarks in this article!

Example Result

Clicking the button should open a new UI Builder Page in a new tab, as shown in the below screenshot

find_real_file.png

 

Tables and relations

Due to the modularity of the Next Experience framework, there are a few steps to take, in order to wire things together. Below is a view of the involved tables. The number indicates the recommended order to create or review the artifact.

find_real_file.png

I recommend filtering the navigator by Actions and Events.

To learn more about the used Declarative Actions and the involved tables, I recommend reading @Ashley Snyder's great article Next Experience - Declarative Actions

Step details and remarks

1. Action Assignment sys_declarative_action_assignment

Access via menu Action Bar Declarative Actions. The recommended convention for action name is lowercase with dashes, for example, action-name. Before saving, create step 2. Action Payload Definition

2. Action Payload Definition sys_declarative_action_payload_definition

The convention here is UpperCase Underscore, ie: PAYLOAD_DEFINITION
A sample payload is:

{
"route":"my-uib-page",
"fields":{
    "table":"{{table}}",
    "sysId":"{{sysId}}" 
    }
}

Be sure to change the route to match the name of the (to be created) UI Builder page.
After submitting the record, you save the Action Assignment record, started in step 1.

3. UX Form Action sys_ux_form_action

Be sure to set the Action Type as Declarative Action and select the appropriate table.

4. UX Actions Configuration sys_ux_action_config
If you're working on an existing Workplace Experience, there probably already is a record you can leverage. For example for CSM / FSM Configurable workspace open the CSM/FSM Configurable Workspace Action Config record.

If you create your own Action Configuration, you must copy the sys_id of the newly created record.
Open the UX Page Registry of the experience and in the related list, UX Page Properties create or update actionConfigId with this value.
find_real_file.png

 

5. UX Action Configurations (M2M) sys_ux_m2m_action_assignment_action_config
From the Action Configuration record, you can create this m2m record via the related list All Declarative Action Assignments. If you do not have the new record, check the video.

6. UX Form Actions Layout sys_ux_form_action_layout
Be sure to check if you need to create this record, or if there is an existing one that matches Action Config (workspace) and Table open that on.

Note that if you leave the field Action Config empty, your action will be available in all Workspace Experiences. In this case, this is not a good idea, as our UI Builder page is not available in other Experiences.

find_real_file.png

7. UX Form Action Layout Item  sys_ux_form_action_layout_item
This is accessible from the related list UX Form Action Layout Items. Create one via the New button or the open in new tab trick mentioned before.

8. Sys Ux M2M Action Layout Item sys_ux_m2m_action_layout_item
This record is auto-generated. It is recommended to open it and change the table name from Global to the appropriate one.

9. UX Add-on Event Mapping sys_ux_addon_event_mapping

This last table can be filled with the following values:

Source element ID: ui_action_bar
Source Declarative Action: The Action just created; ie. ci-dashboard
Parent macroponent: Record (search the one used in your experience)
Target event: RECORD#NAV_ITEM_SELECTED
Target payload mapping:

Note: if you want to open the tab as a subtab of your current record, use the payload snippet @Ashley Snyder shared in the comments, using the "targetRoute": "current" notation.

{
    "type": "MAP_CONTAINER",
    "container": {
        "route": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "route"
                ]
            }
        },
        "fields": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "fields"
                ]
            }
        },
        "params": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "params"
                ]
            }
        },
        "redirect": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "redirect"
                ]
            }
        },
        "passiveNavigation": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "passiveNavigation"
                ]
            }
        },
        "title": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "title"
                ]
            }
        },
        "multiInstField": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "multiInstField"
                ]
            }
        },
        "external": {
            "type": "EVENT_PAYLOAD_BINDING",
            "binding": {
                "address": [
                    "external"
                ]
            }
        }
    }
}

UI Builder page

After this, all is finished you can check if everything works, if you already have the UI Builder page ready, or start working on that if not.

If things don't work as expected, go through the setup, check the tables and check if you're not referencing records used for other experiences.

I also found that running cache.do and reloading the page may help if the events are not emitted after creating them.

Good luck and leave a comment if this helped, or when you have questions!

 

Comments
JagjeetSingh
Kilo Sage
Kilo Sage

I remember struggling with this a while back. Now I know that I was choosing wrong target event. Thank you @Arnoud Kooi for sharing this with us. 🙂

 

Ashley Snyder
ServiceNow Employee
ServiceNow Employee

Exploring this I found you can open the page in a sub-tab by adding "targetRoute": "current",   to the Target Payload Mapping on the UX Addon Event Mapping:

 

{
            "type": "MAP_CONTAINER",
            "container": {
              "route": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                  "address": [
                    "route"
                  ]
                }
              },
              "fields": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "fields"
                    ]
                  }
              },
              "params": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "params"
                    ]
                  }
              },
              "redirect": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "redirect"
                    ]
                  }
              },
              "passiveNavigation": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "passiveNavigation"
                    ]
                  }
              },
              "title": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "title"
                    ]
                  }
              },
              "multiInstField": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "multiInstField"
                    ]
                  }
              },
              "targetRoute": "current",
              "external": {
                "type": "EVENT_PAYLOAD_BINDING",
                "binding": {
                    "address": [
                      "external"
                    ]
                  }
              }
            }
          }

 

 

 

Vijay Kumar1
Tera Contributor

HI,
Thanks for the great article.
I want to add subMenuTab things like: when i hover on New Case, will show three options and then i want to open a form to create new record. can we do that.
Please provide json for that.

thanks in advance

MichaelZischeck
Kilo Sage

i feel stupid... I get the action displayed... but nothing happens when I click it...

 

 

 

chadlockwood
Kilo Sage

cache.do FOR THE WIN! I have spent an embarrassing about of time trying to figure out why my declarative action wasn't opening the popup. Going through the list of tables to make sure that there was an associated record, which there was, and the a cache.do and Viola! it is working now.

Thank you so much for sharing your knowledge with us.

DeveloperK
Mega Explorer

I get the action is displayed, but nothing happened event I do chache.do. Please help me what I missed?

Version history
Last update:
‎12-12-2022 02:53 AM
Updated by:
Contributors