Skip to main content

Extend modern commands with custom pages and geospatial mapping

Headshot of article author Alfredo Cerritos

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.

Open Contacts Map
Use commanding to display a custom control image

Walkthrough

In this walkthrough, we will be using custom pages, map control, and app notifications for plotting a contact’s address on a map.

Map for an individual record image

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.

Open Contacts Map
Open contacts map image
Send notification to CEO or VP with link to map
Send notification to CEO or VIP with link to the map image

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

Go to admin center
Enable maps

Let’s start with creating a solution, model-driven app, and contacts

  1. From your Power Apps portal, go-to solutions and create a new solution
  2. Create a new model-driven app
  3. Open the model-driven app
  4. Add the contacts table to your model-driven app
  5. 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

  1. From the solution, add a blank canvas app. See Create a blank canvas app from scratch
  2. Add a data table that uses contacts as the data source. See Data table control in Power Apps
  3. Add the map control. See Use an interactive map control in Power Apps
  4. 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
  5. 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
Map properties image
Map advanced current latitude and longitude properties image

Create a custom page

  1. From your solution open the model-driven app.
  2. Click the top + Add page button. See Add a custom page to your model-driven app
  3. 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
    1. 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
    2. When prompted select to use JavaScript
    3. From the left pane, add a new dropdown using the +New button
    4. You will see a group is added by default
    5. From the left pane select the group and using the same +New button create a command button under the group
    6. Create a local JS file and add the JS script below to open a centered dialog window.
    7. Click + Add library link
    8. Click + new web resource
    9. Upload your file and enter all the fields.
    10. Select your new library
    11. Enter the name of the function in this case openCustomPage. See Use commands with custom pages with cloud flows
    12. 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’)

  1. While still on the command designer, select the group again
  2. Add another command using the +New button create command button
  3. Add the below JS as a web resource just like you did above and this time the function name is sendNotification.
  4. 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.
  5. 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