Power Apps Custom Page Modal Dialog For Model-Driven Apps

Power Apps Custom Page Modal Dialog For Model-Driven Apps

Power Apps custom pages can be used to build a modal dialog in model-driven apps. A modal dialog is a pop-up menu that lets the user fill in some information then click OK or cancel. This technique requires a little bit of JavaScript code. But don’t worry. If you’re a JavaScript beginner I’ve got code you can copy and paste into your own model-driven app to make it work. In this article, I will teach you how to make a Power Apps custom page modal dialog.

Table of Contents
• Introduction: The Review Comments Dialog BoxAdd A New Custom Page To The Model-Driven AppConfigure The App Display SettingsSetup The Custom Page App Object And ScreenCreate The Custom Page Modal Dialog Main ContainerInsert A Comments Box Into The Modal DialogCreate OK and Cancel Buttons For The Modal DialogAdd A Button To The Main Form Command BarAdd JavaScript Code To The Button To Open The Modal DialogWrite The JavaScript Code To Open The Modal DialogTest The Custom Page Modal Dialog




Introduction: The Review Comments Dialog Box

The I/T department uses the Asset Checkout app to manage loaning devices for users. The Reviews table stores user reviews for the device they borrowed. Comments can be edited using a modal dialog built using a custom page.




Create A New Power Apps Model-Driven App

Open Power Apps Studio and navigate to the Create page. Select the Asset Checkout model-driven app template.



Click the Create button.



The Asset Checkout app will open in the model-driven app editor.





Add A New Custom Page To The Model-Driven App

Press the Add page button in the model-driven app editor




Select Custom page.



Choose Create a new custom page called Review Modal then click the Add button. This will open a new custom page in the canvas app designer.




Configure The App Display Settings

In Power Apps Studio, the custom page will appear on the screen as a full-size page. To make the modal dialog smaller, open the Advanced Settings menu and go to Display. Change the Width and Height to 600 x 300 pixels. Also, toggle off the Scale to fit option. This will allow the modal dialog to become responsive and properly sized on mobile, tablet and PC.




Setup The Custom Page App Object And Screen

We will starting building the custom page modal dialog by updating the app object.



Write this code in the OnStart property of the app object. It gets the recordId from Dataverse and stores it in a variable called gblReviewId. The GUID is in the format “{725851A0-B573-4A33-B609-DA0F2E202EFA}” so we must remove the curly braces and change the data type from string to GUID.

Later in this tutorial, we will learn how to pass a GUID to the modal dialog using URL parameters. Nothing should appear in the custom page at this point. Then we use the variable gblReviewId to obtain the Review record from the reviews table and store it in a variable named gblReview.

Set(
    gblReviewId,
    GUID(Mid(Param("recordId"),2, Len(Param("recordId"))-2))
);
Set(
    gblReview,
    LookUp(
        Reviews,
        Review = gblReviewId
    )
)



To use the Reviews table in the OnStart property code make sure it is added to the Data menu.



Also, change the minimum screen width and height to 200 x 200.

MinScreenHeight: 200
MinScreenWidth: 200



Then set the width and height of the screen named Review Modal.



Set the following properties to change the screen width and height. The height property uses a formula to check whether the app is running in studio mode or in play mode. In play mode, the modal dialog comes with a header that is 53 pixels tall. Therefore, when we are in studio mode we must decrease custom page modal dialog height by 53 pixels.

We will set the pagetype URL parameter later in the tutorial. For now, enter the code shown below and trust me that it will work.

Height: App.Height - If(IsBlank(Param("pagetype")), 53)
Width: Max(App.Width, App.MinScreenWidth)


Create The Custom Page Modal Dialog Main Container

Add a vertical container to the screen to hold all of the dialog’s controls.



Position the container in at X & Y co-ordinates (0, 0) and set the width and height to match the size of the screen.

Height: Parent.Height
Width: Parent.Width
X: 0
Y: 0



We want controls placed inside the main container to flow from top-to-bottom and stretch to fill the size of the container.



Use these values to define the LayoutJustifyContent and LayoutAlignItems properties of the container.

LayoutJustifyContent: LayoutJustifyContent.Start
LayoutAlignItems: LayoutAlignItems.Stretch




Insert A Comments Box Into The Modal Dialog

The key feature of the modal dialog is text box to display comments and let user make edits. Insert a text input into the main container.



Use this code in the Value property of the text input (modern control). It will display the current record’s comments when the model-driven app is in play mode, but not in studio.

gblReview.Comments



Ensure the text input’s Align In Container property is “Set by Container.” This will make it stretch to fill the available space.




Create OK and Cancel Buttons For The Modal Dialog

The modal dialog’s OK and Cancel buttons will be placed below the comments box. Create a new horizontal container to hold them.



Set the Justify property of the container to End and the Align property to Top.



Insert a button into the horizontal container with the text “OK.”



Use this code in the OnSelect property of the button. It saves text from the comments box to the current record and closes the modal dialog using the back function.

Patch(
    Reviews,
    gblReview,
    {Comments: txt_Modal_Description.Value}
);
Back()



Insert another button into the horizontal container with the word “Cancel.”



Use this code in the OnSelect property of the form to close the modal dialog without saving.

Back();



We are now done building the canvas app. Save and publish the app. Then the close the canvas app editor.




Add A Button To The Main Form Command Bar

Now that the Review Modal custom page is completed we will add a button to the model-driven form so a user can open it. Go back to the model-driven app editor and click the three dots beside the Review Table. Choose Edit Command Bar.



Select Main form.



In the command bar edit, go to the ribbon menu and choose New > Command.




Add JavaScript Code To The Button To Open The Modal Dialog

Select the newly added button from the center menu of the screen. Give the icon a label called “Open Dialog” and choose an icon for it. Then update the Action dropdown to Run JavaScript and select Add Library.



On the Add JavaScript library menu click New web resource.



Then Power Apps will navigate to this screen.




Write The JavaScript Code To Open The Modal Dialog

Now we need to write some JavaScript code to open the custom page as a modal dialog. If you have not written any JavaScript code before, don’t worry. I will provide you with the necessary code you can copy and paste into a text file while making only a few minor changes.


Copy and paste this code into Windows Notepad and save it as a Javascript file (extension .js). You will need to update the name parameters with your own custom page’s logical name.

function openCustomPageDialog(primaryControl, firstSelectedItemId, selectedEntityTypeName)
{
    // Centered Dialog
    var pageInput = {
        pageType: "custom",
        name: "cr5b0_reviewmodal_57388",
        entityName: selectedEntityTypeName, // "sample_review"
        recordId: firstSelectedItemId // "{087AA308-B321-E811-A845-000D3A33A3AC}" 
    };
    var navigationOptions = {
        target: 2,
        position: 1,
	height: {
	    value: 260,
	    unit: "px"
	},
	width: {
	    value: 50,
	    unit: "%"
	},
	title: "Edit Comments"
    };
    Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
        function () {
            // Refresh the main form when the dialog is closed
            primaryControl.data.refresh();
        }
    ).catch (
        function (error) {
            // Handle error
        }
    );
}



Get the logical name by going to the Solutions menu in make.powerapps.com, go to the Default Solution, choose the Pages category and look for the Page. The logical name is displayed in the Name column.



Save the JavaScript file and upload it in the command bar editor. Click save and publish.



As a final step, set the command button parameters as shown below. These values get passed into the JavaScript function when the Open Dialog button is pressed.

  • Parameter 1 – PrimaryControl (identifier for the open dialog button)
  • Parameter 2 – FirstPrimaryItemId (current record GUID)
  • Parameter 3 – SelectedEntityTypeName (table name)



Save and Publish the command bad and then press Play.




Test The Custom Page Modal Dialog

It’s time to test our custom page modal dialog. Open the model-driven app in play mode and select Reviews. Open the first record in the app.



Click on the Open Dialog button.



The Power Apps custom page modal dialog appears on the screen!





Questions?

If you have any questions or feedback about Power Apps Custom Page Modal Dialogs For Model-Driven Apps please leave a message in the comments section below. You can post using your email address and are not required to create an account to join the discussion.

Matthew Devaney

Subscribe
Notify of
guest

26 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Sarah
Sarah
1 year ago

Great step by step. If you add the “use strict” statement to your javascript you’ll avoid warnings in the solution checker. Also, you can copy and paste the name of the custom page from within the model driven app designer, rather than having to type it, that saves me some time.

Uliana
Uliana
1 year ago

Thank you for your article!

May I ask you a question regarding Custom buttons in the Model Driven app?
Currently, we are not allowed to use some PowerFx functions here (for example, User() – https://learn.microsoft.com/en-us/power-apps/maker/model-driven-apps/commanding-use-powerfx).
However, I need to hide buttons for specific users. Do you know how we can achieve this now?

Many thanks,
Uliana

Uliana
Uliana
1 year ago

Thank you!

Sarah
Sarah
1 year ago
Reply to  Uliana

Depending on your use case you may be able to use Datasourceinfo or RecordInfo functions. For example we use RecordInfo.DeletePermission to know if the current user has access to delete the current record and show/hide a button accordingly.

Jon Russell
1 year ago

Hey Matthew, how are you doing?

Just a quick one to say, you are missing a closing curly bracket on the end of the javscript code.

Jon

Sean Hodkinson
Sean Hodkinson
1 year ago

Thanks Matthew, this is really interesting and highlights the convergence of Model Driven apps and Custom Pages. I also removed the Review Modal custom page from Navigation in the Model Driven app editor.

Gavin
Gavin
1 year ago

Great article. I’ve only recently started to extend myself from Canvas Apps to Model, so being able to combine the best of both worlds is fantastic. One thing I’ve been looking to do but haven’t been able to figure out yet is how to embed a canvas app in a model form passing the current record context.
It looks like it can be done, but if you’ve looking for new articles to write … (hint hint).

Neil
Neil
1 year ago

Hi Matthew. Great tutorial as always – really appreciate all your content. My first go at a modal on a custom page, I adapted to my solution table names etc and all works beautifully – so thanks. The one thing that I am stuck on though is the modal displays as in the image attached – with the buttons cut off halfway. Have you come across this before?

ModalBox.png
Geremy
Geremy
7 months ago
Reply to  Neil

Got the same issue. I think there are a few instructions he isn’t providing that are key for the dialog and component sizing.

Tomasz
Tomasz
1 year ago

Hi Mathew, great article! I found your blog from the XrmToolCast episode you were on recently 😉

I wanted to ask how do you then hide the custom page from the model driven app navigation section (the left panel). I want to use the custom page only as a dialog an not have the page be visible in the app site map. Do you have any recommendation?

Emily
Emily
1 year ago

Hi Matthew, thanks for your nice article, it’s exactly what I need in my MD APP! But after I click the button nothing happens. I’ve check several times for my setting and cannot find any reason. Could you please give me a suggestion what could be the possible reason? Thank you!

question.png
Eric Brown
Eric Brown
11 months ago

Matt, huge fan.

In your example, the OK button appears to update the underlying Dataverse record. Would it be possible to update one (or more) of the form fields instead? This would leave those fields (and the form) in a ‘dirty’ state that the user could save or exit without saving. “Patch” writes to the record. Can I simply update the form fields from this popup custom page? I can do it from a JS function. What about Fx?

Emma
Emma
11 months ago

Hi Matthew! Thanks for the article it’s really useful.
I wondered if it would be possible to use a lookup field to provide a list for the user to choose from in the modal?

gfreeman
gfreeman
10 months ago

great step-by-step tutorial as usual, thanks a lot!

S P
S P
9 months ago

Hi Matt…love your tutorials and content. I didn’t see a comment about this…and I am going to test here in a second, but I noticed in the js you have firstSelectedItemId as the second input parameter, but in the command button parameters you set the second parameter as FirstPrimaryItemId. I am using this on a form and was getting blank using firstselected on both, so I am going to try firstprimary on both. I assume they should be the same.

Dariusz
Dariusz
7 months ago

Hi Matt,
Is there a reason why in script you have firstSelectedItemId but later in Parameter2 you select FirstPrimaryItemId?

rdtr
5 months ago

This article is very good

Last edited 5 months ago by rdtr
Pradipta
Pradipta
4 months ago

If I add the Custom page to the Tab of the Form. There is no option to send Parameters. Even the modeldrivenformintegration component not available if I don’t edit in Classic mode.