Blog, Development

Xrm.Navigation.navigateTo – gotchas, tricks and limitations

Here are ways that were used by developers to show Modal Dialogs:

  1. Xrm.Internal.openDialog
  2. Alert.js
  3. Custom Dialogs that used different frameworks like jQuery UI Dialog or similar

But the main and common issue of options available was that those approaches can’t be considered as supported.

And it stayed the same for years until Microsoft introduced Xrm.Navigation.navigateTo method.

So what’s new here?

Here is the code that can be used to open a modal dialog:

So far so good. When this code is called following dialog window is shown:

First thing that I’m not comfortable with is the fact that the header of the dialog just uses the name of the webresource that’s not friendly at all. I found only unsupported way to set it so far. Following code added to the onload script of the dialog sets the header’s label:

Once code is added, dialog starts to look friendlier:

Next part is extraction of parameters passed to the webresource. Firstly I tried getQueryStringParameters of GlobalContext in two combinations – GetGlobalContext().getQueryStringParameters and Xrm.Utility.GetGlobalContext().getQueryStringParameters and both calls did not bring the expected result. So… the last resort is explicit parsing of the url. Following code can be used for parsing:

Now let’s make this dialog look closer to standard dialogs and add “OK”/”Cancel” buttons to it. There are multiple ways of doing this. I decided to use “Office UI Fabric” for this purpose. Here is the code of the dialog page:

Here is how it looks like after modifications:

Unfortunately there is only unsupported way to close dialog at the moment. Following code can be used to close it:

In order to return data from dialog set returnValue of window object in dialog and include parameter to “resolve” handler of promise in calling code.

26 Comments

  1. Hi Andrew, note that in chrome the title is in h1#defaultDialogChromeTitle.
    They should really provide a way to set the title on load (even the webresource has another name…)

    1. Thanks, Thomas. That’s why code that used to work earlier doesn’t work anymore.
      Andrew

    2. Regarding Header of the Dialog window .. i was able to specify the display name in the Solution . (Web resource display name in the solution/customization window).

  2. Hi.. Andrew, Thanks for this post. It was really helpful .. Regarding Header of the Dialog window .. i was able to specify the display name in the Solution . (Web resource display name in the solution/customization window).

    Thanks,
    Sumit

    1. This doesn’t seem to work on Chrome?
      The Display name of the Web Resource is not the title for me.

  3. How can I access Xrm.WebApi within the HTML resource?
    So that I can create a Note (annotation Entity) when someone clicks “OK”.

    Thanks!

    1. At the moment keeping in mind deprecation of ClientGlobalContext.js.aspx this fall your best chance is either usage of Xrm.WebApi through parent.Xrm.WebApi or usage of pure XrmHttpRequest from the context of the webresource.

  4. Data parameter is no more supported. Can you Please check as it is crashing when we send parameters as shown above

  5. Passing data is not more supported as per document. Can u Please suggest any way to pass as above code is not working for passing data to web resource

    1. Harkamal,
      I checked what you said and everything works fine for me. If it works for me and doesn’t work for you I believe there could be an issue in your code.
      Andrew

  6. Hi there,
    instant of parent … you can us it like this

    Xrm.Navigation.navigateTo(dialogParameters, navigationOptions).then(
    (result) => this.handleChangeResult(result),
    (error) => this.handleError(error));

    And on the html dialog you can set:
    window.returnValue = { success: true, phonenumber: this.result};

    So this should be completely supported.

    1. Andre, thanks for your comment. In my post I use parent for manipulation with Title and for closing of the dialog and not for sending the result back to the calling code. Is there any alternative to that?
      Andrew

      1. I use this earlier too, but there is a porblem by validating the code with MS tools, because parent is unsupported.
        So I change to set window.returnValue and close the window.
        inside the successhandler, the result is this returnValue you set to window.returnValue

        1. Andre, I got that point.
          What I meant – are there any supported alternatives on how to close the window from the code or how to change the title in the supported way (i.e. without using parent)?
          Andrew

        2. sorry I can’t answer your replay.
          Now I got your problem, I don’t think so because what you call ‘title’, should be somthing like ‘address’. I think this is not well thought out by microsoft right now, maybe there will be a update some time.

  7. Andrew, good morning.

    Could you help me?

    I’m doing with html/js and using your code to open dialog.
    Until now, everything is fine, but i found a problem. After I fill data, we have to do some processes.
    My old dialog uses ‘Start child workflow, Change record status to, create related entity’.

    How do I do this in custom code?
    I’m reading about and looks like ‘Workflows will deprecated’.

    So, i’d like to ask to you what can I do or what you’d do.

    1. Do you think if I use some ‘webapi.update field’ to fires a plugin (to do above operations of old dialog’, will it work in future?
    2. Sdk.rest will be deprecated?
    3. Do you recommend WebAPI? If yes, do you know if old bugs with external webresources still exists? Below:

    Example:
    window[“ENTITY_SET_NAMES”] = window[“ENTITY_SET_NAMES”] || JSON.stringify({
    “contact”: “contacts”,
    “email”: “emails”,
    “account”: “accounts”
    });
    window[“ENTITY_PRIMARY_KEYS”] = window[“ENTITY_PRIMARY_KEYS”] || JSON.stringify({
    “contact”: “contactid”,
    “email”: “emailid”,
    “account”: “accountid”
    });

    4. I had to use these code above in another situation, because i couldn’t retrieve or create record without to do this. Do you think this will be fix in the future?

    Thanks!!

    1. Felipe,
      1. I would recommend to put your logic to action and call it using WebApi.
      2. I believe Sdk.Rest is a wrapper on top of old odata2 endpoint – and it would be deprecated some time so it’s time to switch to WebApi.
      3. I do recommend usage of WebApi. I know what you’re talking about and you have to either use this approach or use parent.Xrm.WebApi… I know that usage of parent is not recommended but at the moment in some situations it’s the most optimal way.
      Andrew

      1. Ok. I understand!

        So, about action, you mean, create an action on process (like workflows) e call using webapi? Could you give me a example or some information to read? Because i’m new in this part.

        Thanks!!

        1. Felipe, sure.
          Here is how you can call the plugin when an action is invoked – https://www.magnetismsolutions.com/blog/dominicjarvis/2017/09/18/how-to-trigger-plugins-on-custom-messages-using-actions-in-dynamics-365
          What you will have to do is to place your logic inside your plugin (writing the code and no fancy UI…)
          To build the code that calls action using WebApi I highly recommend CrmRestBuilder – https://github.com/jlattimer/CRMRESTBuilder/releases/tag/2.6.0.0
          Feel free to ask more question if you have issues.
          Andrew

  8. Many thanks, Andrew. Helped me a lot!!

    I did connection between action interface-plugin code, did logic too, described on link.

    But i still don’t get it how to call Xrm.WebApi.online.execute with parameters, sorry :/

    Because i’m looking everywhere, but i didn’t find how to pass parameters, any types (lookup, entity, string, int).

    And i still one doubt. Do I need to declare input/output parameters in both action interface and plugin code or just in one of it?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.