Sometimes you have a step in a process which is so complex you want to guide the user. You can guide the user by giving him steps of Tasks to do. But what Tasks do you present to your user? What if those steps of Tasks depends on variables that require human interpretation? We can create a Custom Page Dialog to Guide the user what Tasks to generate! That concept is exactly what I want to show you in this blogpost.
We will extend a process I have written extensively about. The Case of the Broken Screen. In one of the steps we sometimes have to coordinate repair work. And sometimes we have to coordinate sending replacement parts. All the while by personally informing the customer. To manage this we we will be using the Tasks set-up from this Blog post on our Case table. This allows us to relate Tasks to the case we are working on.
But what Tasks to work on? Let’s open the Generate Tasks Custom Page Dialog to create them!

What’s a Custom Page Dialog?
Now that we’ve seen the functionality in action, let’s break it down and see how to build it! First a quick explanation what a Custom Page is. A Custom Page is a way to add Canvas App into model-driven apps. You can add Custom Pages as a full page, a side pane or a pop-up like we are doing now with the Dialog example. Custom pages have a few different controls then standard Canvas Apps. These controls use Fluent UI, that will give you the same look and feel as your Model-Driven App.
I will not go over all the specifics to build your first Custom Page. To build your first Custom Page take a look at this introduction on Microsoft Learn. I will however give you the generic steps I took to create my page and to add it to the Model-Driven App.
- Create a Custom Page from within the solution you are working in.
- Press New -> App -> Page.
- Build your Custom Page. See the next paragraph on what I’ve build.
- Press Save and give your Custom Page a name.
- Publish the Page.
- Add the Custom Page to your App in the Designer.
- On the Pages menu press Add Page.
- Choose Custom Page and Press next.
- Pick the Page you want. Deselect the “Show in Navigation”. My example shows a Dialog, not a full page.
- Press Save and Publish the App.

The Task Generator Custom Page Dialog
The focus of this Blog is the concept of the Task Generator so I will not go into too much detail on the Canvas App. I will give a summation of what the App is about. I will, however, show you the code of the creation of the Tasks.
In the Custom Page I want to help users generate Tasks that our organization defined the users needs to do to resolve the Case. So based on the resolution of the Case we generate a Task. This is what the first step of our Dialog is about. If, in our example, we need to send a replacement for the screen, our logistic department need to send it. Thus for this action we will generate a Task in the last step of the App.

After the resolution is selected and we press next. I hide the container for step 1 and show the container for step 2. In this next step the user choses who he wants to inform. For this I create a basic list of checkboxes so the user can decide to inform multiple parties.

Now keep in mind that this is just to show the basic concept. You can imagine a more complex scenario that requires multiple touch points or follow-ups in a process, we can create those Tasks too when a Checkbox is selected. Or we can set “Due Dates” on the Tasks, depending on the type that you selected.
The Code behind the Generate button
Lets take a look at he Power Fx Logic when we press the Generate button. For refence, you can look at it below. I have narrowed down the code to only include one example of the possible different outcomes. There are a couple of bits worth highlighting:
- The possible choices of the radio buttons in Step 1 come from a table of choices. I use a switch statement to determine what Task to create depending on the Selected Value of the Radio Button called “rad_Resolution”.
- The creation of the Dataverse Task record is for now simplistic. A simple subject string and then the Task will also be bound to the Case record we are working on. To bind a Dataverse Task you have to fill in the Regarding field with a LookUp.
- The Case we are working on we retrieve from the Param(“recordId”). We will, in the next step, call this Custom Page Dialog using JavaScript and Modern Commanding.
// Resolution Table({Key: 1, Value:"Send replacement"},{Key: 2, Value:"Repair"},{Key: 2, Value:"Dismiss"})
Switch(
rad_Resolution.Selected.Value,
"Send replacement",
Patch(
Tasks,
Defaults(Tasks),
{
Subject: "Send replacement screen",
Regarding: LookUp(
Cases,
Case = GUID(Param("recordId"))
)
}
),
"Repair",
Patch(...)
"Dismiss",
Patch(...)
);
// Communication
If(
chk_InformManagement.Checked,
Patch(
Tasks,
Defaults(Tasks),
{
Subject: "Inform Management",
Regarding: LookUp(
Cases,
Case = GUID(Param("recordId"))
)
}
)
);
Back();
Calling the Page using Modern Commanding
Now that we’ve build the Custom Page and included it in our application, we need to make sure we can actually call it as a Dialog! I want to add a button on the Main Case Form. Previously we had to use the community tool RibbonWorkBench to add buttons to the Ribbon. Now some functionality of that tool finds its way to the App Designer. With Modern Commanding we can add our own buttons to the Ribbon. To access Modern Commanding go to the Pages tab of the App Designer. Select the table you want to edit and press the more (“…”) buttons and select Edit command bar.

You can edit different kind of ribbons of the table individually. In our example we want to edit the Main Form ribbon. Next we choose if we want to use Power Fx for our command, or if we want to use JavaScript. Currently it is not possible to call a Custom Page as a dialog using Power Fx. So we have to choose JavaScript.
I add a button I name “Generate Tasks”. From the already available Icons I choose one I think defines my use case the most. Then for the Action I choose Run JavaScript. The library (which I provide and explain below) I add and pick here. Next I enter the function in the library with the name “OpenCustomPageDialog”. This function requires 3 parameters. First, the PrimaryControl, so we can refresh the page after the Dialog closes. Second is the FirstPrimaryItemId which I use in the Custom Page Dialog to relate Tasks to the Case. And third is the SelectedEntityTypeName, so we can check if the Dialog is actually bound to the case.

The JavaScript
The JavaScript function is not much different then the functions provided on the Learn page from Microsoft. It is also explained a lot better then I can do in a single blogpost. But again I want to highlight a couple of points:
- The pageInput variable defines where we want to Navigate To and what parameters we want to pass to the page.
- The Modern Commanding interface gives a Guid of the CaseId with brackets. The Canvas Apps prefers Guids without brackets. For that reason I replace the brackets inside this JavaScript function
- The navigationOptions variable defines how and where the Dialog will show.
- After the Custom Page Dialog closes, the form will refresh. We can do this by adding code to the function block after the “then” part of the navigateTo function.
function OpenCustomPageDialog(primaryControl, id, entityName) {// Centered Dialog
var pageInput = {
pageType: "custom",
name: "bdenb_taskgeneratordialog_ca3fc",
entityName: entityName,
recordId: id.replace(/[{}]/g, ''),
};
var navigationOptions = {
target: 2,
position: 1,
title: "Task generator"
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions)
.then(
function () {
primaryControl.data.refresh()
}
).catch(
function (error) {
// Handle error
}
);
}
There you have it! All the steps you have to do to get this Custom Page Dialog concept to work. You can now tinker it to make it work for your scenario. I think concepts like these where we can combine the flexible user experience with Model-Driven Apps is really powerful. And on top of that, building these can be great fun! Please let me know what you think and if you use concepts like these in your own applications!