Opening Entity records with Xrm.Navigation.NavigateTo

Opening Entity records with Xrm.Navigation.NavigateTo

One thing I’ve been waiting a while for is the functionality that allows an entity record (say Opportunity Close) to be opened as a modal window in front of the current window.

Now I know that I could already do this with a Quick Create Form but that results in the Entity appearing in the Quick Create list which may not be the desired result if you want to use the entity to close a task or process (say on Case close or Opportunity won) rather than starting a new task.

The 2020 wave 1 April / May release finally offers the option with Xrm.Navigation.navigateTo, but as it differs in a couple of ways from the old Xrm.Navigation.OpenForm command and has a nasty context issue that will catch you out, it’s worth going over it in more details.

Using navigateTo

The command itself is:

Xrm.Navigation.navigateTo(pageInput,navigationOptions).then(successCallback,errorCallback);

and because it’s a generic command you can play with this yourself on any entity form by opening your browser’s developer console, and entering the following command.

Xrm.Navigation.navigateTo({pageType:"entityrecord", entityName:"contact"}, {target: 2, position: 1, width: {value: 50, unit:"%"}});

And as this is a modal window you can only access the contact record, the account record beneath the record is inaccessible. Only when you close the window can you edit the old record.

Expanding and closing

The modal window offers 2 right hand navigation options, one that maximizes / minimizes the modal window size, the other closes the window.

navigateTo has two input parameters, a pageInput object that determines what will be displayed, and a navigationOptions object that determines how and where it will be displayed.

pageInput

the pageInput object uses the following attributes:

pageType

A required String either “entitylist”, “entityrecord”, “webresource”

entityName

The logical name of the type of entity the entitylist or entityrecord will be displaying

entityId

The id / guid of the entityId to be displayed *if you want to show an existing record. The Guid is without brackets {}.

data

A dictionary object of any fields you wish to prepopulate as you create the new record. For instance {hdn_closetype:”lost”}. This is identical the form parameters that were passed separately when using Xrm.Navigation.openForm.

createFromEntity

allows you to pass in a Lookup to prepopulate the new record with the mapped attribute values specified in the relationship between the lookup and the new record. The lookup object has 3 attributes, entityType, id and name (optional). While the name field is optional where possible you should pass it within the object as otherwise the system will display a default value which may cause confusion.

Note: https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/reference/xrm-navigation/navigateto lists another set of options but I will ignore those for now as they relate to Business Process Flow requirements that I suspect most people won’t need to worry about.

Navigation Options

target

Target is a required (number) field that offers two options:

A value of 1 opens the form inline (replacing the current page), 2 opens the form in a dialog -which is what we require for our purposes.

Note: web resources and entity forms can be opened both inline (target:1} and as a dialog {type: 2} but entity lists can only be opened as an inline resource.

One of the catches we have discovered will show why later.

Position

Only used for Dialog windows (target:2}. 1 opens the dialog in the center, 2 opens it to the right (same as a Quick create form).

Size

Width and optionally height can be set using a SizeValue type {value: Number, unit: string either “%” or “px”}

Return Values

As with most functions in the Xrm library Xrm.Navigation.navigateTo returns a promise. When the return is triggered depends on the target of the window, for inline targets {target:1} (replacing the existing page) the promise is resolved immediately, for dialog targets {target: 2} (modal window / dialog on top of the existing window) the promise is resolved when the dialog is closed.

If an entityrecord is opened in a dialog in create mode the promise will receive a savedEntityReference array to identify the created record.

var pageInput = { 
	pageType: "entityrecord", 
	entityName: "account" 
}; 
var navigationOptions = { 
	target: 2, 
	position: 1,
	height: {value: 80, unit:"%"}, 
	width: {value: 70, unit:"%"} 
}; 
Xrm.Navigation.navigateTo(pageInput, navigationOptions).then( 
	function success(result) { 
		console.log("Record created with ID: " + result.savedEntityReference[0].id + " Name: " + result.savedEntityReference[0].name) 
		// Handle dialog closed 
	}, 
	function error() { 
		// Handle errors 
	} 
);

Resolving the promise is actually more important than you would expect as issues with context I’ve discovered below will reveal.

The issue of Context

The new functionality is sadly not perfect. As I’ve been playing with the functionality, I have encountered two separate issues connected with the system’s awareness of current context which could cause problems.

Adding a second record

Clicking New in the modal window may not do what you think it will do. It doesn’t as you might expect reopen open a fresh form in the modal window it instead opens it in the main form overriding what was previously there.

Context

The second issue requires a tiny bit of background knowledge, that D365 / powerapps remembers in the background the current entity / entity Type it is dealing with.

Now that has never previously been an issue as there has only ever been 1 core entity on the screen but now you can add a second (or even a third, by using both positions) entity it’s no longer so clear cut and the newly created / saved record will override the information in the background.

The video below shows a quick example of the issue – as the contact record is saved the context is switched from account to contact as pressing F5 in this video shows.

F5 form refresh doesn’t work

As you can see upon saving the contact form in the dialog window the application context switched from the account record you half expect it to be to the contact record that had been closed.

To avoid this and return the context to what the user is probably expecting (the account record) you need to refresh / reload the account form within the success function of the promise.

The code sample below does exactly that. As part of the initialisation of the dialog window we create a separate object containing the account information so that when the dialog is successfully closed we can refresh / reload the account window and the context is restored.

this.resolveCase = function(context){
var id=context.data.entity.getId().replace(/[{}]/g,"");
var ef = {};
ef["pageType"]= "entityrecord";
ef["entityName"] = "contact";   ef["formType"]=2;
    ef["cmdbar"]=false;
    var createFrom ={};
    createFrom ["entityType"]= "account";
    createFrom ["id"]= id;
    createFrom ["name"] = context.getAttribute("name").getValue();
    ef["createFromEntity"]=createFrom;

    var es = {};
    es["entityName"] = "accounbt";
    es["entityId"]=id;

    Xrm.Navigation.navigateTo(ef, { target: 2, position: 1, height:{value: 600, unit:"px"}, width: {value: 500, unit:"px"}}).then(
        function(){Xrm.Navigation.openForm(es)});    
};

No Comments

Post A Comment