The Power Platform Chap

Benjamin Crowe

Custom Model Driven App Commands

Introduction

Model-driven applications are powerful ways we can allow our end users to interact with business data. In a matter of minutes, we can get an app up and running, which will give access to large collections of data, without having to worry about the record limits or delegation woes of canvas applications. This speed and power come with some limitations to what can be achieved with out-of-the-box model-driven applications. Sometimes you get a requirement that can’t be solved with an out-of-the-box app, this is where we need custom model-driven app commands.

Getting ready to customise

One way to bring customisation to model-driven apps is via the command bar. This post will guide you through creating a custom command to add to a model-driven app. To begin with:

  1. Navigate to solutions using the left-hand navigation menu, either create a new solution or pick one that already exists.
  2. Create a model-driven application or choose one that is already in the solution.
    • To create an app, choose +New > App > Model Driven App.
    • Then give your new app a name
Creating a Model Driven app

Once you have your model-driven app containing the required Dataverse tables, in-depth information on building model-driven apps, can be found here.

Customising the command bar

To edit the command bar first find the target table, from the Pages section of the app designer.

  1. Click on the three ellipses next to the chosen table … > Edit Command Bar > Edit.
Selecting Edit command bar in the pages menu of the model driven app studio

The next allows us to pick which one of the table command bars we want to add the custom command.

  • Main grid – This places the command on the main grid view this is handy when you’re building customisations that will be used either to create a new record or manage multiple records at once.
  • Main form – The custom command will be visible on the main forms command bar, handy when you want to enable more custom control over an individual record.
  • Subgrid view – Your custom command will be viewable on subgrids when you reference this table within forms from related tables across your application.
  • Associated view – Puts a custom command on the command bar of the associated view which can be accessed in the main form from the Related tab.

More information about the different command bar locations can be found here.

Selecting the location of the command bar to add the custom command.

In this example, we will add a custom command to the record’s main form. Once selected click edit.

A picture of the command bar designer

This will open the command designer for our given command bar. To begin with we need to add a command to the bar.

  1. To do this we will need to click on + New > Command
  2. This will give the option, to create our new custom command using PowerFx or Javascript.
Menu popout giving option to create either a PowerFx or JavaScript custom command.

Power Fx

Power Fx can be used to control not only the action of the command but also its visibility. When this option is chosen the command will have a formula bar similar to that seen in the canvas app development experience. As such when working with Dataverse tables you can use Power Fx formulas as you would when designing canvas app functionality.

JavaScript

JavaScript is a high-level, interpreted programming language that is widely used across all aspects of the internet. It is also supported in both modern and classic commands. Modern controls make the process of utilising this robust programming language fairly simple. This guide will create a custom command using JavaScript.

The Command

In this guide, we will make two simple commands. One is a simple HTML screen with a very familiar sentence. The other is possibly more likely to come up when designing amazing solutions for your end users.

HTML Pop Out

For this first example, the command will show an HTML pop-out which displays ‘Hello World’ to the user. To achieve this first we need some web resources, in this example I have used the following for the HTML:

<html lang="en">
<style>
    body{
        background-color: #f0f0f0;
    }
    h1{
        text-align: center;
        margin-top: 100px;
        font-size: 50px;
        color: #333;
        font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
    }
</style>
<body>
    <div>
        <h1>Hello World</h1>
    </div>
</body>
</html> 

Below is the Javascript code, which calls the HTML page.

loadHelloWorld = function() {
    var pageInput = {
    pageType: "webresource",
   webresourceName: "bcdev_helloWorldHTML"
};
var navigationOptions = {
   target: 2,
   width: 400,
   height: 300,
   position: 1
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
   function success() {
    // Handle dialog closed
          console.log("Inside Success");
   },
   function error() {
         Xrm.Navigation.openAlertDialog({ text: error.message });
   }
);
}
  1. With the new command added to the bar, we need to name it.
  2. An optional extra is associating a web resource icon for the command to give it visual uniqueness.
Image showing new custom control in command ribbon editor.
  1. Then under ‘Action’ select ‘Run JavaScript’
  2. Choose the web resource library that you want to use. Please note that the list you will see contains all the libraries currently in use.
  3. To add a new library click + Add Library
  4. Search for the library you wish to use and click Add.
Image showing how to add the JavaScript library to use in the custom control.
  1. Enter the name of the function being called.
  2. Add the following parameter:
    • PrimaryControl (identifier for the control)
  3. Click save + publish.
Image showing parameter needed for custom web resource pop-out control

With that, the command is complete, open your updated model-driven app, navigate to a record and click the newly created custom command:

Finaly image of HTML Pop-out

Canvas Page PopOut

Loading custom HTML pages is one thing, though what about a modal dialogue box, a pop-up that allows users to input information against a given record? We shall take a look at this next, creating a custom page which we will use to interact with one of our records.

Custom page

First, let’s walk through, the process of creating the custom page for our model-driven app.

  1. To do this we need to click on + New > App > Page
New custom page menu

Once the design studio is open, the first step is to change the canvas size to our preferred height and width.

Display settings of custom canvas page.

With this done we have a blank canvas to create the layout of our modal dialogue box. For this example, I have added some inputs which will display the book title and author. Though more importantly for this demo, allow end users to enter notes on the book record selected.

Image of custom canvas page app.

Next, select the App level in the left-hand tree view, and choose the ‘OnStart’ property from the drop-down menu in the formula bar. We need to enter the following code into this property:

Set(
    gblBookDetails,
    GUID(Mid(Param("recordId"),2, Len(Param("recordId"))-2))
);
Set(
    gblBook,
    LookUp(BookInformations,
    BookInformation = gblBookDetails
    )
);

If you’re following this post and are seeing an error which says “Name isn’t valid. ‘BookInformations’ isn’t recognized” this is because we are still needing to add the Book Information table to the page.

  1. This is done on the Data menu. Click Data > + Add data > choose the table you need.
OnStart property code which runs when the custom pop-out first loads

To display the values in both the Title and Author text inputs, we set the value property in both to the following:

gblBook.Title
gblBook.Author
Image showing how the title information is shown in the canvas page using a global variable.

Image showing how the Author information is displayed in the Author text input on the canvas page.

Along with the Title and Author inputs, I also added a multi-line text input to capture any notes the end users wish to add to the record. To round off this custom app page, we simply need to add two buttons, one to submit the notes back to the record, and the other to cancel and close the popout window.

For the Submit button the following code needs to be added to the ‘OnSelect’ property:

Patch(
    BookInformations,
    gblBook,
        {
            Notes: txtNotesFormContentHome.Value
        }
);
Back();
Image showing Patch function in the OnSelect property of the Submit button.

The Cancel button needs a single line of text to close the pop-out window.

Back();
Image showing 'Back()' command for the onselect property of the cancel button.

Adding the control

Adding the control button to the command bar follows the same steps as the HTML pop-out, the difference here is that we will be using a different web resource library. The JavaScript below is what we shall use to call the custom page and then display it to the end user.

function loadCustomHelloWorld(PrimaryControl, FirstSelectedItemId, SelectedEntityTypeName){
    var pageInput = {
        pageType: "custom",
        name: "bcdev_custompagepopout_d30d9",
        entityName: SelectedEntityTypeName,
        recordId: FirstSelectedItemId
    };
    var navigationOptions = {
        target: 2,
        position: 1,
	    height: 800,
	    width: 600,
	    title: "Edit Notes"
    };
    Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
        function () {
            PrimaryControl.data.refresh();
            // This refreshes the form after the dialog is closed to show the updated data
        }
    ).catch (
        function (error) {
            // Handle error
        }
    );
}

The other difference between this example and the previous one is the parameters that are passed to the JavaScript from the custom control.

Image showing parameters to include for custom control.

These are:

  • PrimaryControl (identifier for the control)
  • FirstPrimaryItemId (This is the GUID to the record)
  • SelectedEntityTypeName (This is the name of the table the record is from)

Once the control has been added, it is important to remember to add your custom page to the model-driven application.

  1. Click ‘+ Add page’ > ‘Custom Page’
Image showig how to add a Custom Page to a model-driven app.

When adding your custom page, if it is not meant to be accessible directly from the navigation pane on the left of you’re model-driven application, remember to un-check ‘Show in navigation’.

Image showing selected custom page and making sure 'Show in navigation' is un-checked.

For this example, I’ve added a notes field to the form shown in the application, using the new custom command will allow my end users to amend the notes section.

Image showing new field in model-driven form.

Image showing custom page pop-out with updated notes section.

Using FirstPrimaryEntityId allows details from the selected record to be passed to and from the custom page. Once the notes have been completed clicking Submit on the custom pop-out will save this information back to the record using the Patch command.

Image showing updated record in the mode driven app.

Conclusion

So there we have it, creating custom controls for your model-driven apps. Although out-of-the-box model-driven apps offer excellent functionality, incorporating custom commands can significantly enhance your users’ experience. I hope this post has provided valuable insights and practical guidance for integrating custom commands into your next project, elevating the overall performance and user satisfaction of your model-driven apps.

If you liked this post why not check out ‘Power Apps – Sending Outlook Emails in Canvas Apps’

Leave a comment

Leave a Reply

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