ecLearn - Learning Management System built on top of Microsoft Dataverse for Power Platform and Dynamics 365 users

ENGINEERED CODE BLOG

Power Pages: Pro Code Techniques in the Templates – Custom Interface for Location Selection

This month we continue our look at some of the pro code techniques that appear in the templates available for Power Pages. We’re going to stick with the “Schedule and Manage Meetings” template, which provides a multistep form for booking a meeting. This time we’re going to look at the second step, where a user can select which location they want their appointment at. This step includes some custom JavaScript, plus a PCF Control.

Selecting a Location

When you get to this page for the first time, you get to choose whether you want a virtual appointment, or to visit a branch. You do this by picking from a radio button list, which is tied to a choice field on the Appointment Request table. Note that it is displayed as a radio button list because there is form metadata configured to transform it from the typical HTML element for a choice field, which is a dropdown – no custom code was used to do that.

After selecting an option, you’ll see a PCF Control displayed – it allows the user to enter a ZIP code, which will then display a list of branch locations near that ZIP code. If you’re using the test data, try using 98011 as your ZIP code.

Clicking on a branch in the list will take you to the next step of the form.

If you look at the underlying Dataverse form for this step, you’ll see:

Basically, the choice field to select either branch or virtual, followed by the PCF Control, and then a location Lookup.

Basic Custom JavaScript

If we look at the Custom JavaScript for this Multistep Form Step, you’ll see some basic code to start:

Line 2 hides the Location lookup on the form. We don’t want the user to see that field – it’s there so that when we select our location via the PCF Control, we can set the input and have that value saved as part of the form submission.

Line 3 hides the ZIP code PCF Control – it is only shown after the user chooses between virtual or in-branch meeting.

Both lines 2 and 3 use the name of the section to target the element they wanted to hide.

Lines 4-5 hides the “Unavailable” option for the Bank Appointment Type choice field. This option isn’t something they wanted users on the site to be able to select.

Lines 7-9 show the ZIP code PCF control when an appointment type is chosen, and lines 11-13 show it if the choice is already made when the page loads (which happens if the user navigates back to this step from the next one).

Custom Validator

Next, custom JavaScript is used to add a custom validator to ensure the user select a branch before moving forward:

I think this is something that could’ve been done with Form Metadata instead – even if the field is hidden with JavaScript, the validator should still fire.

Location Selection JavaScript

Finally, we’ve got the JavaScript that handles when a user chooses a location.

Starting on line 52, we’re handling three events:

  1. Blur: if a user uses a keyboard to navigate the list, this handler updates the hidden location inputs. To proceed, the user would need to click the Next button, or hit Enter (see event #3).
  2. Click: if a user clicks on a branch, the hidden location inputs are set, and the navigation to the next step happens automatically.
  3. Keydown: if the user hits enter after selecting a branch using the keyboard, the hidden location inputs are set, and the navigation to the next step happens automatically.

The selectLocation() function on line 35 sets the name and ID of the selected location, and sets the inputs for the Location lookup. Remember that when dealing with a lookup in JavaScript, there are three inputs: the name of the row, the ID of the row, and the table name.

Interaction with PCF Control

For the most part, we have to treat the PCF Control like a black box. Microsoft doesn’t provide us access to the source code. The best we can do is look at the JavaScript using the Developer Tools in our browser. The PCF Control is built using React and TypeScipt, so what we see in the browser is the raw JavaScript that is transpiled from the React project.

I did peek around in the code a bit, and at a high level the control:

  • Gets a list of all of the branch locations during initialization.
  • When a ZIP code is entered, it finds any branch where the first two digits of the ZIP code match. Then it uses the Bing Maps API to determine the distance from the entered ZIP code to the branch, and displays up to the five closest results.
  • While the PCF Control is bound to the ZIP code column on the Appointment Request form, the control never sets this value, so that column will always be empty in Dataverse.

Since the PCF Control doesn’t update a field on the form, how does the communication between the PCF Control and the rest of the form work? The short answer is by convention.

As we saw in the previous section, in the custom JavaScript on the form there are events tied to clicking on a branch or selecting one with the keyboard. This relies on the elements in the list to have certain classes (ms-DetailsRow and ms-List-cell).

While it might just be my personal preference, this technique is not my favourite. This is mostly because the events that are handled in the custom JavaScript are bound to the body, since the elements that we want to target aren’t available when the document is ready (which makes sense – those elements are created each time a search is done). While filters are put on the event handler to make sure we’re only notified when an event we care about happens, under the hood there is still code that needs to run for every blur, click and key down to check if it is one we care about. Not a huge deal, but still not ideal. This is the sort of technique you’d use when you don’t control one side of the code. But in this case, I have to believe that even if the same developer wasn’t doing the custom JavaScript and the PCF Control, at the very least they were working together.

My preference would have been for the PCF Control to provide a bit more of an explicit way of communicating with the form. Perhaps a parameter could be passed to the control telling it the name of the Lookup column so that it could set the values itself. Or the PCF Control could have updated the field it was bound to, and then the custom JavaScript could have been listening to changes on that field.

Again, this isn’t a huge deal, just my personal preference.

You might be wondering why the PCF Control wasn’t bound to the Location lookup, since that is where it ultimately was trying to save the data to. Unfortunately, it is not yet supported to have a PCF Control bound to a lookup column.

PCF Control vs Custom JavaScript

Instead of a PCF Control, it is possible that similar functionality could have been built directly into the custom JavaScript section. Or a stand-alone React app could have been created. But since this is part of a Power Pages template, I like that it was a PCF Control.

The reason is because it gives Microsoft a way to provide updates to the code.

When it comes to providing updates to a Power Pages site, Microsoft does provide updates to solutions that you can install. Since PCF Controls are contained in solutions, if Microsoft updates the PCF Control code in the solution and you install that solution, you’ll get the updated code. However, when it comes to actual data in Dataverse, Microsoft does not provide any mechanism to update this, beyond manually changing the data yourself.

So if the code for the ZIP code search was contains in the Custom JavaScript section, or in a Web File, you’d be stuck with that version, unless you updated it manually. With a PCF Control, Microsoft has an easy way to provide updates.

When it comes to providing reusable functionality within Power Pages templates that Microsoft can actually maintain, PCF Controls are the way to go.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact

Engineered Code is a web application development firm and Microsoft Partner specializing in web portals backed by Dynamics 365 & Power Platform. Led by a professional engineer, our team of technology experts are based in Regina, Saskatchewan, Canada.