Blog

Custom Dialog Boxes - Part 2

– 4 Minutes

In Part 1, I introduced Dialog Boxes and showed the basics of how to create one and import it through a solution. In this post, we'll take a look at a few other features including passing data parameters into the dialog and adding event handlers on form load or on click of a button.

Note: although I said I considered this supported in Part 1, this is currently a preview feature, and it is therefore not yet released/supported by Microsoft. Please do not use this in a Production environment.*

Parameters

Parameters are used to pass data into your dialog. These can be used, for example, to pass in an entity type code and entity id which you can use to save that back to an entity during the process flow.

Defining a parameter is very easy. In the <form> tag, simply add a block like this:

<form>
  <formparameters>
    <querystringparameter name="id_ID" type="SafeString" />
    <querystringparameter name="id_Type" type="Integer" />
  </formparameters>
  ...
</form>

The valid types values are: Boolean, DateTime, Double, EntityType, Integer, Long, PositiveInteger, SafeString, UniqueId, and UnsignedInt.

Also, all query string parameter names must begin with "id_" in order to pass the solution import validation. Seems kind of arbitrary, but I'm sure there's a perfectly logical reason behind it.

To pass the data into the dialog when we open it, simply adjust the call to openDialog. The third parameter is a JavaScript object which has keys that match the names of the query string parameters.

var options = {
  dialogName: 'custom',
  position: 1,
};
var data = {
  id_ID: '00000000-0000-0000-0000-000000000000',
  id_Type: 1
}
Xrm.Navigation.openDialog("CustomDialog", options, data);

Passing data into the dialog isn't very useful, unless we can do something with the data. In order to do that, we can use event handlers, but before I cover that, let's take a look at how we can add multiple pages/tabs to our dialog.

Pages

In our dialog box, we can have multiple pages which are defined as "tabs" in the Form XML. Effectively, we can just create a copy of the tab we created in the previous post and change some of the ID's and Names. When you're done it should look something like this:

<tabs>
  <tab id="{...}" verticallayout="true" name="Tab1">
    <tabfooter id="{...}">
      ...
    </tabfooter>
    <columns>
      ...
    </columns>
  </tab>
  <tab id="{...}" verticallayout="true" name="Tab2">
    <tabfooter id="{...}">
      ...
    </tabfooter>
    <columns>
      ...
    </columns>
  </tab>
</tabs>

On their own, we won't be able to navigate from page to page. In order to do that, we must have some buttons on the form with onclick event handlers.

Event Handlers

Just like on an entity form, we can add event handlers to a dialog box. For example, we can have a form onload event handler which reads the input parameters and does something with them, or we can have an onclick event handler on a button to move us to the next/previous page.

Both of them are used the same way - you simply define them under the <events> node.

<form>
  ...
  <events>
    <event name="onclick" application="false" active="false" attribute="tab2footerclose">
      <Handlers>
        <Handler functionName="onClick_Close" libraryName="bg_CustomDialog_Library.js" handlerUniqueId="{ADC7E877-6FDC-4404-8744-A85F607A5095}" enabled="true" parameters="" passExecutionContext="false" />
      </Handlers>
    </event>
    <event name="onload" application="false" active="false">
      <Handlers>
        <Handler functionName="onLoad" libraryName="bg_CustomDialog_Library.js" handlerUniqueId="{124A0213-CE38-4F33-93C9-7D2B2BD83006}" enabled="true" parameters="" passExecutionContext="false" />
      </Handlers>
    </event>
  </events>
</form>

You'll notice that the event handlers reference a JavaScript web resource file. This file is just like any regular JavaScript file you use to add form scripts to an entity form. In order for our solution to import successfully, we must also add a reference to the web resource in our customizations.xml file.

<ImportExportXml>
  ...
  <WebResources>
    <WebResource>
      <WebResourceId>{f192e5a1-c78d-e811-a95b-000d3a18b4b9}</WebResourceId>
      <Name>bg_CustomDialog_Library.js</Name>
      <DisplayName>CustomDialog_Library.js</DisplayName>
      <WebResourceType>3</WebResourceType>
      <IntroducedVersion>1.0.0.0</IntroducedVersion>
      <IsEnabledForMobileClient>0</IsEnabledForMobileClient>
      <IsAvailableForMobileOffline>0</IsAvailableForMobileOffline>
      <DependencyXml><Dependencies><Dependency componentType="WebResource"/></Dependencies></DependencyXml>
      <IsCustomizable>1</IsCustomizable>
      <CanBeDeleted>1</CanBeDeleted>
      <IsHidden>0</IsHidden>
      <FileName>/WebResources/bg_CustomDialog_Library.js</FileName>
    </WebResource>
  </WebResources>
</ImportExportXml>

And then also add a reference for the RootComponent the solution.xml.

<RootComponent type="61" schemaName="bg_CustomDialog_Library.js" behavior="0" />

Finally, if your [Content_Types].xml file doesn't have a type for JavaScript files, you must add it (note: this is necessary if you are using a solution file that does not yet contain any JavaScript files). With all of the files updated, we can package and deploy the solution to test it out!

Testing

Once the solution is imported, let's test it out. Go to a Unified Interface app, drop into the developer console for the browser, and run the Xrm.Navigation.openDialog(...) command from above. This should open the dialog like so.

Dialog box example 1

And clicking the Next button will take us to the second page!

Dialog box example 2

Pretty neat, eh?! In the next post, we'll look at adding custom controls onto the form. That's where it really gets fun :)

You can download the solution file I used for this post here: CustomDialogs_1_0_0_1.zip.

Comments

Billy

Hello Bob! Great guide. Thanks so much. Are you going to write the Part 3? Do you know how can I read an official guide on this topic or tell me how to add a lookup on a Dialog Box?
Kind regards

Michael

Hi Bob,

Thanks for the great article! I tried to import your solution to my D365 v9.1 but it failed.

Microsoft must have changed something.

Regards,
Mihailo

Praveen Thonda

Hi Bob,
Can a html Webresource placed inside of this Dialog?

Jack

Hi Bob,

Can't wait for Part 3...

Regards

Bhasker

Hi Bob,

This is really great solution. Will this solution supported by Microsoft, because SDK does not have much details building custom Dialog Boxes and Xrm.Navigation.openDialog method.
Do you know where we can find classid's for all controls node.

Regards,

Bob Guidinger

Hi Bhasker,

As mentioned at the top of this post, this is not officially supported.

BM

Hi Bob,

Now PCF framework in public preview. Did you see any update on official support on this solution.

thanks,
BM

Jide Bantale

Thanks bob. This is a great solution. Microsoft have enable customizations on of one the dialogs(possible opportunity), so I want to believe they will allow custom dialogs to be created or at least be on their roadmap.

This is a great one Bob.