Extend modern commands with custom pages and geospatial mapping
Buttons and command bars control the core behavior for any application. Without them, we can’t print the latest report, start our time-sensitive process, or make our hero storm the castle and save the day in our favorite video game. In Power Apps Model-Driven Apps, they are everywhere, and this blog will show you how to leverage geospatial features with modern commands, custom pages, model-driven apps, and a little bit of JavaScript.
Walkthrough
In this walkthrough, we will be using custom pages, map control, and app notifications for plotting a contact’s address on a map.
What if you wanted to plan your trip around town to visit clients to be more effective and review the relative locations of your clients? And what if you were asked to do this by your CEO or VP and needed to let them know it was ready to view and where to find this map in your model-driven app? You could build them a beautiful app that looks something like this.
Setup
We need to create a custom page with a map control that will read contact data. What ingredients do we need to build all this? A solution, model-driven app, contacts, canvas app, custom page and JavaScript.
Prerequisites
As an admin, go to the admin center, turn on geospatial controls and turn on Bing Maps. Detailed steps are here Add geospatial controls to canvas apps and Manage Bing Maps for your organizations
Let’s start with creating a solution, model-driven app, and contacts
- From your Power Apps portal, go-to solutions and create a new solution
- Create a new model-driven app
- Open the model-driven app
- Add the contacts table to your model-driven app
- Go to contact and enter new contacts with addresses using the main Contact form. Enter City, State/Province, Country/Region
For more information Create a model-driven app using the account page
Create canvas app
Why do we need a canvas app? You can copy and paste controls that aren’t shown on a custom page from a canvas app. In this case, we want the map control
- From the solution, add a blank canvas app. See Create a blank canvas app from scratch
- Add a data table that uses contacts as the data source. See Data table control in Power Apps
- Add the map control. See Use an interactive map control in Power Apps
- Enable the Show current location property and use the formula bar to set the CurrentLocationLongitude and CurrentLocationLatitude So that when the user selects a row, the map highlights the location with a blue circle
- When you’re happy with formatting the data table and map. Select the controls and on your keyboard, use CTRL+C. See Copy and Paste controls across Canvas Apps available
Create a custom page
- From your solution open the model-driven app.
- Click the top + Add page button. See Add a custom page to your model-driven app
- While on the custom page use CTRL+V to add the data table and map to your custom page. See Copy and Paste controls across Canvas Apps available
Open your map from a button
- From your solution open the model-driven app and navigate to command designer. When prompted leave the default to the Main grid. See Open the app designer
- When prompted select to use JavaScript
- From the left pane, add a new dropdown using the +New button
- You will see a group is added by default
- From the left pane select the group and using the same +New button create a command button under the group
- Create a local JS file and add the JS script below to open a centered dialog window.
- Click + Add library link
- Click + new web resource
- Upload your file and enter all the fields.
- Select your new library
- Enter the name of the function in this case openCustomPage. See Use commands with custom pages with cloud flows
- Enter the custom page logical name as the first param and the page title as the second param. See Use Javascript for actions and Finding the logical name
For more information see Create and edit web resources
Example code for openCustomPage sample function
function openCustomPage(customPageLogicalName, customPageTitle) {
// Opens a centered custom page dialog
let pageInput = {
pageType: "custom",
name: customPageLogicalName,
};
let navigationOptions = {
target: 2,
position: 1,
width: { value: 50, unit: "%" },
title: customPageTitle,
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions)
.then(function () {
// Called when the dialog closes
})
.catch(function (error) {
// Handle error
});
}
Add send notification button
To get this working we are going to need to get the system user id. You can use OData to get the system user id quickly using this snippet. As a test, you can use your own system user id before sending it to someone. See User (SystemUser) table/entity reference
Example query
/api/data/v9.0/systemusers?$select=fullname&$filter=startswith(fullname,’Alfredo C’)
- While still on the command designer, select the group again
- Add another command using the +New button create command button
- Add the below JS as a web resource just like you did above and this time the function name is sendNotification.
- Enter the system user id of the person to see the notification as the first param. Enter the page title as the second param and the custom page URL for the third param.
- When you are done save and publish your changes
Example URL
?appid=0b02a3a4-16da-ec11-bb3b-000d3a33d9bf&ribbondebug=true&pagetype=custom&name=cr1c6_contactslocations_24f66
Example code for send notification function
function sendNotification(systemuserid, customPageTitle, customPageUrl) {
var notificationRecord = {
"title": "Congratulations",
"body": "You can review the location of your contacts",
"ownerid@odata.bind": "/systemusers(" + systemuserid + ")",
"icontype": 100000001, // success
"data": JSON.stringify({
"actions": [{
"title": customPageTitle,
"data": {
"url": customPageUrl
}
}
]
})
}
Xrm.WebApi.createRecord("appnotification", notificationRecord).
then(
function success(result) {
console.log("notification created with single action: " + result.id);
},
function (error) {
console.log(error.message);
// handle error conditions
});
}
? Congratulations!
Now you have your map and a way to notify your CEO or VP that it’s available. The next time they open the app they will see the notification and can click on the link to review the map. Note that the JS functions are reusable, and can be applied for different tables such as Accounts, Organizations, etc.
You can discover your own scenarios. One example is you are planning a conference with different event locations.
Team Credits
Huge thanks to the commanding engineering team. Alfredo Cerritos LinkedIn, Anshul Jain LinkedIn, Brad Flood LinkedIn, Casey Burke LinkedIn, Prabhat Pandey LinkedIn, Sanket Patadia LinkedIn, Sergio Escalera Costa LinkedIn, Srinivas Dandu LinkedIn
Thanks to Scott Durrow LinkedIn, Adrian Orth LinkedIn for collaboration