We're reclaiming inactive PDIs to keep them available for active builders. Learn what's changing, who's affected, and how to protect your work. Read More

How to open a record in a new SOW internal tab from a UI Page embedded in g_modal.showFrame

NeelyC
Tera Contributor

Hi everyone,

I am working in Service Operations Workspace (SOW) and trying to implement a specific navigation behavior.

The Architecture: I have a Workspace UI Action on the Incident form. When clicked, it opens a modal using g_modal.showFrame(). Inside this modal, I load a custom UI Page. The UI Page runs a Client Script that uses GlideAjax to fetch related records (Incidents/RITMs) and dynamically builds an HTML table to display them.

NeelyC_0-1784546583513.png

 

The Goal:

One of the columns in the dynamically generated HTML table is the Record Number, which needs to act as a link. When the user clicks this link, I want it to:

  1. Break out of the modal's iFrame.

  2. Open the target record in a new internal Workspace sub-tab (within SOW).

  3. Do all of this without performing a hard refresh of the entire browser page.



i am trying to create a link from the Number that will open a new SOW tab in the browser tab i am on without refreshing the page. 

The Issue:

Currently, my working code uses a standard HTML anchor tag:

var sowLink = '/now/sow/record/' + tableName + '/' + sysId;
html += '<td><a href="' + sowLink + '" target="_blank">' + recNumber + '</a></td>';

Because of -target="_blank"- , this bypasses the workspace router and opens the record in a completely new Chrome browser tab, which is not the desired user experience.

 

how showld i reframe this so it will open in the current web browser tab i am on, without refreshing the page?
 what is the Next Experience Best Practice to trigger the SOW router to open a new internal tab?
4 REPLIES 4

Ankur Bawiskar
Tera Patron

@NeelyC 

try to use g_aw.openRecord("incident", sysId);

share your complete script here

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  10x ServiceNow MVP  ||  ServiceNow Community Leader

Hi,

thanks for the suggestion.

Unfortunately, g_aw.openRecord() doesn't work directly in this case.

Since the UI Page is rendered inside an isolated iFrame (via g_modal.showFrame), the g_aw API is undefined within that iframe's scope.

Any other workaround?
Or Suggestions on other ways to implement the same functionality?

Tanushree Maiti
Tera Patron

Hi @NeelyC 

 

1. Use openRecord(String table, String sysId, Object params) 

Refer: Open a new record as a sub-tab in Workspace when clicking a UI Action 

 

2. How to use UI Actions in Workspaces

 

 

Please Accept the solution if it assisted you with your question & Mark this response as Helpful.
Regards
Tanushree Maiti
ServiceNow Technical Architect
LinkedIn: https://www.linkedin.com/in/tanushreemaiti

Rakesh_M
Mega Sage

Hi @NeelyC ,


1.Add a callback function to the workspace client script as shown:

function onClick() {
    var uiPageSysId = '57bf1c48831ac7d0408ec260ceaad379'; // Replace with your UI Page's sys_id
    
g_modal.showFrame({
    title: "Incident Search",
    url: "/ui_page.do?sys_id=" + uiPageSysId,
    size: "xl",

    callback: function(action, data) {

        if (action) {
            g_aw.openRecord(data.table, data.sys_id);
        }

    }
});
}

 

2.Open the UI Page and update the HTML and Client Script as shown below.

 

HTML:

html += '<td><a href="#" onclick="openIncident(\'incident\', \'' + recSysId + '\'); return false;">' + recNumber + '</a></td>';

It should generate HTML as:

<td>
    <a href="#" onclick="openIncident('incident', '15b56b36a36402101509d63f26fcdab1'); return false;">
        INC0010049
    </a>
</td>

 

Client Script: Add following to the client script

var iframeMsgHelper = (function() {

    function createPayload(action, modalId, data) {
        return {
            messageType: 'IFRAME_MODAL_MESSAGE_TYPE',
            modalAction: action,
            modalId: modalId,
            data: data || {}
        };
    }

    function pm(window, payload) {
        window.parent.postMessage(payload, location.origin);
    }

    function IFrameMessagingHelper(window) {
        this.window = window;
        this.messageHandler = this.messageHandler.bind(this);
        window.addEventListener('message', this.messageHandler);
    }

    IFrameMessagingHelper.prototype.messageHandler = function(e) {
        if (e.data.messageType !== 'IFRAME_MODAL_MESSAGE_TYPE')
            return;

        if (e.data.modalAction !== 'IFRAME_MODAL_ACTION_INIT')
            return;

        this.modalId = e.data.modalId;
    };

    IFrameMessagingHelper.prototype.confirm = function(data) {
        pm(this.window,
            createPayload(
                'IFRAME_MODAL_ACTION_CONFIRMED',
                this.modalId,
                data
            )
        );
    };

    return new IFrameMessagingHelper(window);

})();

function openIncident(tableName, sysID) {

    iframeMsgHelper.confirm({
        sys_id: sysID,
        table: tableName
    });

}

 

Now, when you click the Incident Number link in the UI Page, the corresponding incident record opens in a workspace subtab.