logo

NJP

Workspace for a custom app: buttons

Import · Jul 07, 2023 · article

In my previous posts I talked about how to start with Workspace for a custom app and how to configure forms for your records. Now let's talk about buttons.

Now, when forms are configured let's add some buttons. First, let's start with form buttons. Of course, you can just add a button component in UI Builder and configure it to do whatever you want, but I can't think of any reason why it would be a good idea. No, probably I can... Let's not go there and focus on more realistic scenarios.

In my app I'd like to have button that changes the state of the record, so I just created a good old UI Action. To make it visible in the workspace you need to fill a couple additional fields. First, select "Workspace Form Button", then "Format for Configurable Workspace" and finally write what this button should do. Easy!

Screenshot 2023-06-30 at 15.55.56 (2).png

You probably noticed that in workspace all UI Actions work on client side. I'm not sure how I feel about it, but that's the side effect of using workspace. By the way, you can easily have server-side UI Action that executes client-side script in the workspace!

Now my new button is visible in the workspace, but I noticed an issue with position of the action bar.

Screenshot 2023-06-30 at 16.00.35 (2).png

I saw this issue several times before, so I'm pretty sure it's not just my instance. To fix it you'll have to go to UI Builder and play with position of action bar. The way I usually fix it, I select Top Container, set Direction to row and J*ustify content* to space-between.

Screenshot 2023-06-30 at 16.07.16 (2).png

If form buttons can be configured more or less the same way as before, related list buttons are completely different. All related list buttons are located in sys_declarative_action_assignment table. To find them go to Workspace Experience -> Actions & Components -> Related List Actions. Let's play around with them a little.

Hiding New button.

First thing I'd like to do in my app is to hide New button on a related list. If you open Related List Actions and search for New button on Global table, you'll find 4 records. One of them is for m2m tables, another for Service Operations workspace only and the one you need is this one:

Screenshot 2023-07-03 at 15.56.01 (2).png

Open this record and create an exclusion for New button. On Action Exclusions create a new record, select your table name and select Exclude this table checkbox. New button is not visible on the related list anymore!

Screenshot 2023-07-03 at 15.58.49 (2).png

Actions configuration

Next thing I'd like to do is to add a few buttons to m2m table.

But before creating these buttons I'd like to do one more thing - create an action config record. It's not really mandatory, but I find it handy to have one config record with all my custom buttons. Additionally, it provides some styling functionalities. To create new action config go to Now Experience Framework -> Actions & Events -> Ux Form Actions Configs and create a new record. We'll associate all our buttons with this record now.

But we also need to tell our workspace to use this config, so go to UX Application (read about how to do it here), find actionConfigId UX Page Property and replace its value with sys_id of new action config. Now we can continue with buttons.

Screenshot 2023-07-03 at 16.56.56 (2).png

M2M buttons

I'd like to have functionality similar to old UI: New button to create a new record a something like Edit button to associate existing records. But, since it's not old UI anymore, we'll go with 3 buttons instead: New, Add, Remove.

New button

New button should create a new record for a child table and a relationship between parent and child records.

This task is already half-done by ServiceNow, so you need to do just a few things.

  1. First, create a new button, select you m2m table and view you're using in workspace.
  2. Set Action label as New, set something in Action name and select UXF Client Action in Implemented As field.
  3. Now you need to select Create New Record ManyToMany client action.
  4. And the last step, on Action Configurations related list associate you button with Action Config you've created before.Screenshot 2023-07-03 at 17.08.08 (2).png

That's it! You should see you button on the related list now.

Remove button

Now let's add Remove button to delete relationship. It will not delete the child record itself, only relationship between them.

  1. Same as before, create a new button, select you m2m table and view you're using in workspace.
  2. Set Action label as Remove, set something in Action name and select Server Script in Implemented As field.
  3. Save record and select Advanced view.
  4. Select Record Selection Required checkbox. This is needed to select which record we want to remove.
  5. Go to Server Script and write
    current.deleteRecord();​
  6. And the last step, on Action Configurations related list associate you button with Action Config you've created before.Screenshot 2023-07-03 at 17.15.35 (2).png

Add button

Last button we need to configure is Add button. This button should open a modal that allows user to select which child records should be associated with the parent record. To do that we need to use a Multi-Record Associator component in our modal. Thankfully, this modal is already configured OOTB, so we just need to call it.

Create new event

First, we need an event that will open the modal. Since it's a custom workspace there are no pre-configured events in it, so I'll create a new one. I prefer to use one event that will open a viewport modal and to configure all sorts of subpages for this modal. Let's call this event RECORD#OPEN_MODAL, this is how the same type of event is called in OOTB workspaces (but you can call it something else).

  1. Open your record in UI Builder, select top-level component (usually called Body).
  2. Add new handled event to the component.
  3. Call it the way you want, but notice the format of the event name. I'm not sure what will happen if you use other format, but I prefer to stick with it.Screenshot 2023-07-07 at 11.00.18 (2).png
  4. Add payload fields. Since I'm going to use the same event for opening different subpages I need to pass 3 parameters in the payload:
    • route - name of the subpage;
    • fields - required parameters;
    • params - optional parameters.

Screenshot 2023-07-07 at 11.00.24 (2).png

Next step is to open a modal when this event is fired. We are going to open preconfigured modal, you can find it in the modals list (see Modal Container).

  1. Create new event mapping.
  2. Select [Record Page] Open Modal - Data resource event handler. This is an OOTB event handler that will open preconfigured viewport modal.
  3. Fill payload parameters that should be passed, see screenshot below.Screenshot 2023-07-07 at 11.16.04 (2).png

Create Add button

Now the event part is done and we need to create a button that will fire this event. This button is created the same way as all other related list buttons.

  1. Create a new button, select you m2m table and view you're using in workspace.
  2. Set Action label as Add, set something in Action name and select UXF Client Action in Implemented As field.
  3. Now you need to create new client action, let's call it Idea Task MRA. Notice the format of action key (see screenshot below).
  4. Fill the payload of the action. In this payload you need to put the actual values you want to send to the event. For MRA modal they should look like this:
    { "size":"lg", "route": "mra", "fields": { "query": "{{query}}", "table": "{{table}}", "parentRecordSysId": "{{parentRecordSysId}}", "userGivenTable": "x_snc_home_autom_0_automation_task", "label": "Add", "parentFieldName": "x_snc_home_autom_0_automation_idea", "referencedFieldName": "x_snc_home_autom_0_automation_task", "extensionPoint": "DEFAULT", "columns": "number,short_description,state", "hideSelectAll": false, "relatedListName": "{{relatedListName}}" }, "params": { "type": "m2m" } }​
  • route - mra;
  • fields must contain:
    * query - query defined for related list, use {{query}} variable;
    * table - table name of m2m table, use {{table}} variable;
    * parentRecordSysId - sys_id of parent record, use {{parentRecordSysId}} variable;
    * userGivenTable - table name child record;
    * label - title of the modal;
    * parentFieldName - column on m2m table where you store parent record;
    * referencedFieldName - column on m2m table where you store child record;
    * extensionPoint - used to add additional filter to the list shown in the modal. If you want to see all records set it to DEFAULT;
    * columns - columns from child table that you want to show in the modal;
    * hideSelectAll - hides option to select all records;
    * relatedListName - name of the related list, use {{relatedListName}} variable;
  • params must contain:
    * type - m2m (for m2m table).Screenshot 2023-07-07 at 12.44.38 (2).png
    1. On Action Configurations related list associate you button with Action Config you've created before.

Associate button with event

Next, we need to associate our action with the event, so ServiceNow will know which event to fire. To do that on Action Assignment record you've created in step 1 create new Event mapping (via related list).

Screenshot 2023-07-07 at 13.31.14 (2).png

Follow these steps:

  1. Create new Event Mapping.
  2. Fill the fields in the event mapping:
    • Source element ID - id of the component where you button is located. In our example it's related list and component is called list_related (you can find this ID in UI Builder);
    • Source Declarative Action - auto-populated;
    • Parent Macroponent - name of your record page;
    • Target Event - event you created before;
    • Target Payload Mapping - this is mapping between event's payload and client action payload we've created before, for this example you can use this code:
      { "type": "MAP_CONTAINER", "container": { "route": { "type": "EVENT_PAYLOAD_BINDING", "binding": { "address": [ "route" ] } }, "fields": { "type": "EVENT_PAYLOAD_BINDING", "binding": { "address": [ "fields" ] } }, "size": { "type": "EVENT_PAYLOAD_BINDING", "binding": { "address": [ "size" ] } }, "params": { "type": "EVENT_PAYLOAD_BINDING", "binding": { "address": [ "params" ] } } } }​
  3. This is how event mapping should look like:Screenshot 2023-07-07 at 13.31.07 (2).png

Now all 3 buttons should be visible on the related list and work as expected.

Screenshot 2023-07-07 at 13.54.29 (2).png

Control visibility of the buttons

The last thing I'd like to do in this post is to make these buttons visible only under certain conditions. First, they should be visible only to users who has rights to create records in m2m table. Additionally I'd like to show them only when the state of parent record is accepted.

To do this, let's open a button and switch to Advanced view. Now you should be able to see Conditions tab, let's go there. On this tab you can populate role conditions, client conditions (like parent record is new), record conditions and script conditions.

For my scenario I'll add a script condition to show buttons only when parent record is in state "Accepted" ( there is parent variable for it). You can also call a Script Include from this field.

Spoiler

Note! Record Conditions can be used for form buttons, but they will not work for related list buttons.

Screenshot 2023-07-07 at 13.49.02 (2).png

Confirmation message

Oh, and last thing! I'd like to show a confirmation message when I remove a record from related list:

Screenshot 2023-07-07 at 13.52.46 (2).png

Result:

Screenshot 2023-07-07 at 13.54.38 (2).png

In my next post you'll read about how to add some nice UI features to your custom workspace: Workspace for a custom app: headers, highlighted values, sidebar

View original source

https://www.servicenow.com/community/next-experience-blog/workspace-for-a-custom-app-buttons/ba-p/2603633