Navigating to a custom page using client API
This article provides examples of navigating from a model-driven app page to a custom page using Client API.
This article outlines the steps to use client API to open a custom page as a full-page, dialog, or pane. It provides examples of custom as a pageType
value in navigateTo (Client API reference).
Important
Custom pages are a new feature with significant product changes and currently have a number of known limitations outlined in Custom Page Known Issues.
Navigating from a model page to a custom page
Finding the logical name
Each of the following client API examples takes the logical name of the custom page as the required parameter. The logical name is the Name value of the page in the solution explorer.
Open as an inline full page without context
Within a model-driven app client API event handler, call the following code and update the name parameter to be the logical name of the page.
// Inline Page
var pageInput = {
pageType: "custom",
name: "<logical name of the custom page>",
};
var navigationOptions = {
target: 1
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions)
.then(
function () {
// Called when page opens
}
).catch(
function (error) {
// Handle error
}
);
Open as an inline full page with a record context
This example uses the recordId
parameter within the NavigateTo function to provide the custom page with the record to use.
// Inline Page
var pageInput = {
pageType: "custom",
name: "<logical name of the custom page>",
entityName: "<logical name of the table>",
recordId: "<record id>",
};
var navigationOptions = {
target: 1
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions)
.then(
function () {
// Called when page opens
}
).catch(
function (error) {
// Handle error
}
);
The Param
function within the custom page retrieves the value and uses the Lookup function to retrieve the record.
App.OnStart=Set(RecordItem,
If(IsBlank(Param("recordId")),
First(<entity>),
LookUp(<entity>, <entityIdField> = GUID(Param("recordId"))))
)
Important
The recordId
parameter must be a GUID because it updates the URL and an app start from the URL will validate the recordId
is a GUID.
Open as a centered dialog
Within a model-driven app client API event handler, call the following code and update the name parameter to be the logical name of the custom page. This mode supports the sizing parameters similar to the Main form dialogs.
// Centered Dialog
var pageInput = {
pageType: "custom",
name: "<logical custom page name>",
};
var navigationOptions = {
target: 2,
position: 1,
width: {value: 50, unit:"%"},
title: "<dialog title>"
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions)
.then(
function () {
// Called when the dialog closes
}
).catch(
function (error) {
// Handle error
}
);
Open as a side dialog
Within a model-driven app client API event handler, call the following code and update the name parameter to be the logical name of the custom page.
// Side Dialog
var pageInput = {
pageType: "custom",
name: "<logical page name>",
};
var navigationOptions = {
target: 2,
position: 2,
width: {value: 500, unit: "px"},
title: "<dialog title>"
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions)
.then(
function () {
// Called when the dialog closes
}
).catch(
function (error) {
// Handle error
}
);
Open from a grid primary field link as a full page with record ID
This example uses the recordId
parameter within the navigateTo function to provide the custom page with the record to use. The Param
function within the custom page retrieves the value and uses the Lookup function to retrieve the record.
A more complete example of this can be found at Override the default open behavior of data rows in an entity-bound grid.
Create a web resource of type JScript and update the name parameter to be the logical page name. Add the following code to the web resource.
function run(selectedItems) { let selectedItem = selectedItems[0]; if (selectedItem) { let pageInput = { pageType: "custom", name: "<logical page name>", entityName: selectedItem.TypeName, recordId: selectedItem.Id, }; let navigationOptions = { target: 1 }; Xrm.Navigation.navigateTo(pageInput, navigationOptions) .then( function () { // Handle success } ).catch( function (error) { // Handle error } ); } }
Customize the table ribbon CommandDefinition for OpenRecordItem to call the function above and include the CrmParameter with the value SelectedControlSelectedItemReferences.
<CommandDefinition Id="Mscrm.OpenRecordItem"> <Actions> <JavaScriptFunction FunctionName="run" Library="$webresource:cr62c_OpenCustomPage"> <CrmParameter Value="SelectedControlSelectedItemReferences" /> </JavaScriptFunction> </Actions> </CommandDefinition>
In the custom page, override the App's OnStart property to use the
Param
function to get therecordId
and lookup record.App.OnStart=Set(RecordItem, If(IsBlank(Param("recordId")), First(<entity>), LookUp(<entity>, <entityIdField> = GUID(Param("recordId")))) )
Note
After changing the
OnStart
property, you'll need to runOnStart
from the App context menu. This function performs only once within a session.Then, the custom page can use the RecordItem parameter as a record. Below is an example on how to use it in an EditForm.
EditForm.Datasource=<datasource name> EditForm.Item=RecordItem
Open from a selected record in editable grid as a centered dialog with record ID
Editable grid can be used to trigger OnRecordSelect event for scenarios where you want to perform an action when a particular record is selected in a view. This example uses the recordId
parameter within the navigateTo function to provide the custom page with the record to use. The record ID is retrieved using the getId
method in GridEntity object. The Param
function within the custom page retrieves the value and uses the lookup function to retrieve the record.
Enable editable grid control in the table.
Create a web resource of type JScript and update the name parameter to be the logical page name. Add the following code to the web resource.
function RunOnSelected(executionContext) { // Retrieves the record selected in the editable grid var selectedRecord = executionContext.getFormContext().data.entity; var Id = selectedRecord.getId().replace(/[{}]/g, ""); // Centered Dialog var pageInput = { pageType: "custom", name: "<logical page name>", recordId: Id, }; var navigationOptions = { target: 2, position: 1, width: { value: 50, unit: "%" }, title: "<dialog title>" }; Xrm.Navigation.navigateTo(pageInput, navigationOptions) .then( function () { // Called when the dialog closes } ).catch( function (error) { // Handle error } ); }
In the custom page, override the App's OnStart property to use the
Param
function to get therecordId
and lookup record.App.OnStart=Set(RecordItem, If(IsBlank(Param("recordId")), First(<entity>), LookUp(<entity>, <entityIdField> = GUID(Param("recordId")))) )
Note
After changing the
OnStart
property, you'll need to runOnStart
from the App context menu. This function performs only once within a session.Then, the custom page can use the RecordItem parameter as a record. Below is how to use it in an EditForm.
EditForm.Datasource=<datasource name> EditForm.Item=RecordItem
Related articles
Model-driven app custom page overview
Add a custom page to your model-driven app
navigateTo (client API reference)