How to navigate to the correct record page from a Search Input in UI Builder?

ronro2
Tera Contributor
Hi everyone,
 
I’m building a Search Input component in UI Builder that allows users to search for tasks. I’ve already created a Search Configuration that works, but I need help with the next step:
 
Goal:
When I type a case number in the search field and select a result, I want to navigate directly to the correct Record Page for that task.
 
Challenge:
The tasks are stored in three different tables, which are child tables of custom table called x_vgll_rail_task:
  • x_vgll_rail_request
  • x_vgll_rail_ticket
  • x_vgll_rail_demand
Each table has its own record page i UI Builder, for example:
https://<instance>/x/vgll/ass-workspace/rail-ticket-record-page/x_vgll_rail_ticket/-1
https://<instance>/x/vgll/ass-workspace/rail-demand-record-page/x_vgll_rail_demand/-1
https://<instance>/x/vgll/ass-workspace/rail-request-record-page/x_vgll_rail_request/-1
When a record is opened, the URL looks like this:
https://<instance>/x/vgll/ass-workspace/rail-request-record-page/x_vgll_rail_request/<sys_id>
 
Question:
How can I configure the Search Input so that when a result is selected, it navigates to the correct record page based on the table name and sys_id?

Can I use a Client Script for this? Is there a best practice approach?
 
I’ve seen an example where they use following actions Knowledge Center workspace:
  • Search executed: Execute Client Script

/**
 * @Param {params} params
 * @Param {api} params.api
 * @Param {any} params.event
 * @Param {any} params.imports
 * @Param {ApiHelpers} params.helpers
 */
function handler({
    api,
    event,
    helpers,
    imports
}) {
    if (event.payload.searchTerm != "") {
        var isAISearchEnabled = api.data.check_ai_search_satus_1.output;
        if (isAISearchEnabled) {
            const fields = {
                searchContextConfigId: event.payload.searchContextConfigId
            };
            const params = {
                searchTerm: event.payload.searchTerm
            };
            helpers.navigate.to('search-results', fields, params, false, false);

        } else {
            const {
                SEARCH_CONSTANTS
            } = imports["sn_km_center.searchInputUtils"]();
            const fields = {
                globalSearchViewConfigId: SEARCH_CONSTANTS.GLOBAL_SEARCH_VIEW_CONFIG_ID
            };
            const params = {
                searchTerm: event.payload.searchTerm,
                selectedSearchContext: 'now/knowledge-center'
            };
            helpers.navigate.to('kc-zing-search', fields, params, false, false);

        }
    }
}​



  • Suggestion item clicked: Execute Client Script
 
/**
* @Param {params} params
* @Param {api} params.api
* @Param {any} params.event
* @Param {any} params.imports
* @Param {ApiHelpers} params.helpers
*/
function handler({api, event, helpers, imports}) {
const { handleNavigation } = imports["sn_km_center.searchInputUtils"]();
    handleNavigation(api, event, helpers);
}
 
 
 
 
My idea:
I’d like to build a script that:
  • Gets the table name and sys_id from the selected item.
  • Navigates to the correct record page using helpers.navigate.to()(I guess?)
Does anyone have an example of how to do this in a simple and best practice way? Or if you could take inspiration of the example provided? 

Alternatively, how would you handle it if you want this to work directly on the search term (without clicking a suggestion)?

Summary:

  • Three different tables, three different record pages.
  • Need to navigate based on table name and sys_id.
  • Open to best practice tips (Client Script, imports, or other approaches).
Thanks in advance guys!!
1 ACCEPTED SOLUTION

You’re not wrong to think it feels redundant — the confusion is just that in UI Builder “Execute client script” isn’t an event by itself. It’s an action that only runs when you hook it up to an event.

So you don’t really choose between:

  • Content items selected

  • Execute client script

Instead it’s:

Content items selected (event) → Execute client script (action) → your code runs

That’s why when you tried “only Execute client script,” nothing happened — there was nothing triggering it.

Do you need both events?

Only if you want both behaviors:

  • Content items selected = user clicks/selects an item from the suggestions dropdown

  • Search executed = user hits Enter / submits the search

If you want redirect on both click and Enter, you’ll typically wire up both events, but you can reuse the same script (or call a shared function/include to avoid duplicating code).

Why your code isn’t redirecting right now

With the newer UI Builder versions, Content items selected usually returns an array, not payload.item. So your script never finds an item and exits silently.

Try this slight tweak (same logic, just grabs the selected item correctly):

function handler({ event, helpers }) {
  const payload = event.payload || {};
  const item = (payload.items && payload.items[0]) || payload.item;

  if (!item) return;

  const sysId = item.sys_id;
  const table = item.table || item.sys_class_name;

  const pageByTable = {
    x_vgll_rail_ticket:  "rail-ticket-record-page",
    x_vgll_rail_demand:  "rail-demand-record-page",
    x_vgll_rail_request: "rail-request-record-page"
  };

  const page = pageByTable[table];
  if (!page || !sysId) return;

  helpers.navigate.to(page, { table, sys_id: sysId });
}

What I’d recommend

  • If you only care about clicking a suggestion: just use Content items selected → Execute client script

  • If you want Enter to work too: add Search executed → Execute client script as well.

 

@ronro2 - Please mark as Accepted Solution and Thumbs Up if you find Helpful!!

 

View solution in original post

8 REPLIES 8

 

Yes — that’s exactly it 👍

In the newer UI Builder versions, “Suggestion item clicked” has effectively been replaced by “Content items selected.” So you’re on the right track.

What changed is mostly naming and payload structure, not behavior. The event that fires when a user selects a result from the search suggestions is now Content items selected.

Do this:

  • Attach your handler to Content items selected on the Search Input component.

  • That event fires when one (or more) suggestion items are selected.

  • The payload now comes as a collection, not a single item.

The Pattern in the handler:

  • Grab the first selected item from the payload

  • Use its sys_id, table, or sys_class_name

  • Navigate to the appropriate record page

Conceptually:

const item = event.payload?.items?.[0];

From there, your navigation logic stays the same.

Why Knowledge Center still looks different

Knowledge Center may still reference older event names or wrap this logic inside a UX Client Script Include, which hides the event-name differences. Functionally, they’re doing the same thing you’re trying to do — reacting to the “user selected a search result” event.

 

@ronro2 - Please mark as Accepted Solution and Thumbs Up if you find Helpful!!

@Matthew_13, thanks for clarifying this for me! I noticed that scripting can be used directly in the "Content items selected" handler instead of binding data.

However, I have a question: If we use your example for the Execute client script handler with the following code:
function handler({ event, helpers }) {
  const item = event.payload.item || event.payload.selectedItem || event.payload.suggestion;
  if (!item) return;

  const sysId = item.sys_id;
  const table = item.table;

  const pageByTable = {
    x_vgll_rail_ticket:  "rail-ticket-record-page",
    x_vgll_rail_demand:  "rail-demand-record-page",
    x_vgll_rail_request: "rail-request-record-page"
  };

  const page = pageByTable[table];
  if (!page || !sysId) return;

  helpers.navigate.to(page, { table, sys_id: sysId });
}
 
Is there actually any need for a second handler like Content items selected in this case? I tried using the same code in both handlers, but it feels redundant.

What I’m really trying to ask is:
If this code is already in one of the handlers, is there any reason to use both Content items selected and Execute client script? Or would it be sufficient to keep the logic in just one of them?

As of now I tried using only the "Execute client script" handler with your code, but nothing happens. I don't get redirected to the searched record, no matter if I click or enter it. 😞 

You’re not wrong to think it feels redundant — the confusion is just that in UI Builder “Execute client script” isn’t an event by itself. It’s an action that only runs when you hook it up to an event.

So you don’t really choose between:

  • Content items selected

  • Execute client script

Instead it’s:

Content items selected (event) → Execute client script (action) → your code runs

That’s why when you tried “only Execute client script,” nothing happened — there was nothing triggering it.

Do you need both events?

Only if you want both behaviors:

  • Content items selected = user clicks/selects an item from the suggestions dropdown

  • Search executed = user hits Enter / submits the search

If you want redirect on both click and Enter, you’ll typically wire up both events, but you can reuse the same script (or call a shared function/include to avoid duplicating code).

Why your code isn’t redirecting right now

With the newer UI Builder versions, Content items selected usually returns an array, not payload.item. So your script never finds an item and exits silently.

Try this slight tweak (same logic, just grabs the selected item correctly):

function handler({ event, helpers }) {
  const payload = event.payload || {};
  const item = (payload.items && payload.items[0]) || payload.item;

  if (!item) return;

  const sysId = item.sys_id;
  const table = item.table || item.sys_class_name;

  const pageByTable = {
    x_vgll_rail_ticket:  "rail-ticket-record-page",
    x_vgll_rail_demand:  "rail-demand-record-page",
    x_vgll_rail_request: "rail-request-record-page"
  };

  const page = pageByTable[table];
  if (!page || !sysId) return;

  helpers.navigate.to(page, { table, sys_id: sysId });
}

What I’d recommend

  • If you only care about clicking a suggestion: just use Content items selected → Execute client script

  • If you want Enter to work too: add Search executed → Execute client script as well.

 

@ronro2 - Please mark as Accepted Solution and Thumbs Up if you find Helpful!!

 

@Matthew_13 thank you so much for the thorough explanation. 

My collegue found your code so helpful, but he did a little tweak to get it working. 

So, as you said, we used the "Suggestion item clicked" -> Execute client script: 

 

function handler({ event, helpers }) {
  const payload = event.payload || {};
  const item = (payload.actionPayload && payload.actionPayload[0]) || payload.actionPayload;
  console.log(item);
  console.log(payload);
  if (!item) return;

  const sysId = item.sysId;
  const tableName = item.table;
  console.log(tableName);
  const pageByTable = {
    x_vgll_rail_ticket:  "rail-ticket-record-page",
    x_vgll_rail_demand:  "rail-demand-record-page",
    x_vgll_rail_request: "rail-request-record-page"
  };

  const page = pageByTable[tableName];
  if (!page || !sysId || !tableName) {
  return;}

  helpers.navigate.to(pageByTable[tableName], {table:tableName, sysId:sysId});
}

 


Thanks again!!! 😍