Yet Another Address Autocomplete PCF Control–powered by Bing

Andreas CieslikDyn365CE5 years ago39 Views

In this blog post I will not go into detail in how to install all the pre-requisites that are required to build and run PCF controls. My goal was to build a new PCF control and get into coding of PCF controls as fast as possible.

Here are a few links to articles that will help you installing the pre-requisites (Microsoft PowerApps CLI) https://docs.microsoft.com/en-us/powerapps/developer/component-framework/get-powerapps-cli
Other good references to get into this topic:
https://toddbaginski.com/blog/how-to-create-a-powerapps-pcf-control/
https://docs.microsoft.com/en-us/powerapps/developer/component-framework/create-custom-controls-using-pcf
I looked through the Guido Preite’s https://pcf.gallery/ which will help you find appropriate use cases / examples for your own needs. It did not take very long to find a simple example to start with: Andrew Butenko’s https://pcf.gallery/address-autocomplete/
A few moments later I had the idea to create yet another address autocomplete control but this time powered by the Bing API.

Bing Api Key

Reason for that decision is that with a paid Customer Engagement plan or Field Service App license you get the ability to use the D365 instance’s Bing API Key, which can be found under Resource Scheduling => Settings => Administration => Scheduling Parameters.
With the Field Service App license you receive the auto-geocode feature and the geocode button for entities like account or work order. This feature also relies on the Bing API. My idea – using this key for the new Bing auto complete control should do job to make it work without buying an extra license for a Google Maps API Key.
clip_image002
For the next step I researched on how to create a PCF control without doing too much typing in a command prompt console. A very nice and nifty solution is the XrmToolBox plugin “PCF Custom Control Builder” developed by Danish Naglekar. In his blog post he explains more details on his plugin:
https://danishnaglekar.wordpress.com/2019/10/07/pcf-custom-control-builder/
I entered in all the necessary data and followed the steps to build and create this new Bing address autocomplete control:
image
General
1. Control Location: Path of the control project with all dependencies, etc.
2. Visual Studio Command Prompt Location: Path to VS 2017 CMD

Component Details

  1. Namespace
  2. Control Name
  3. Template (optional): e.g. from an existing PCF Gallery’s control
  4. Version: Auto-Incremented
  5. Create Button: Creates initial control structure
  6. Open in VS Code: will open the project’s TypeScript source file in Visual Studio Code Editor
  7. Build: Builds the control
  8. Test will run and open a browser instance with a self-hosted test kit containing your PCF control

Solution Details

  1. Initialize CDS project: Define you Solution name, Publisher name and prefix. Currently, the plugin does not allow spaces in the names.
  2. Deploy to D365 CE: Once the custom control is ready, deploy the control directly in you D365 CE or CDS environment using XrmToolbox connection

Here is the log of my solution create, add and build statements…

Create the solution

image

Add a control reference to the solution

image

Rebuild and bundling of the control from the CDS project

image
image
image
image
image
image
image
image

Deployment & Configuration

Via the “Deploy” button you can easily deploy your freshly made CDS solution to your D365 instance.
Once deployed and published you can go to your entity of choice and configure the control similar to pictures shown below.

This is my test entity “Main Address”

image
The goal is to use the “Name” field to enter an address and to have the Bing autocomplete feature as support to resolve and propose a valid address.
So I open the change properties dialog for this field and configure to use the Bing Address Autocomplete PCF control:

Add control to the Name field

image

Configure the Bing Address Autocomplete control

The configuration allows you to control on which device you can see and use available controls.
Here I chose to use my new control for Web, Phone and Tablet.
Then I linked the entity’s address fields to my control properties.
Last step is to enter a static value for the Bing Api Key.
image
If done, save and publish the changes on the entity form and you are ready to go to try it out.

Final result

On change of the name field the autocomplete control will trigger the dropdown list with suggestions.
image
Once we select an address it will automatically fill in the previously mapped fields of this control and at the end it will look like this:
image

In Action

PCF.BingAddressAutocomple_Min2

The implementation of the control

 /// <reference path="types/MicrosoftMaps/Modules/Autosuggest.d.ts" />

import { IInputs, IOutputs } from "./generated/ManifestTypes";

export class BingAddressAutocomplete implements ComponentFramework.StandardControl<IInputs, IOutputs> {

    private notifyOutputChanged: () => void;
    private searchBox: HTMLInputElement;

    private value: string;
    private street: string;
    private city: string;
    private county: string;
    private state: string;
    private zipcode: string;
    private country: string;

    constructor() {

    }

    public init(context: ComponentFramework.Context<IInputs>,
        notifyOutputChanged: () => void,
        state: ComponentFramework.Dictionary,
        container: HTMLDivElement) {
        if (typeof (context.parameters.bingapikey) === "undefined" ||
            typeof (context.parameters.bingapikey.raw) === "undefined") {
            container.innerHTML = "Please provide a valid bing api key";
            return;
        }

        this.notifyOutputChanged = notifyOutputChanged;

        this.searchBox = document.createElement("input");
        this.searchBox.setAttribute("id", "searchBox");
        this.searchBox.className = "addressAutocomplete";
        this.searchBox.addEventListener("mouseenter", this.onMouseEnter.bind(this));
        this.searchBox.addEventListener("mouseleave", this.onMouseLeave.bind(this));
        if (typeof (context.parameters.value) !== "undefined" &&
            typeof (context.parameters.value.raw) !== "undefined" && context.parameters.value.raw != null) {
            this.searchBox.setAttribute("value", context.parameters.value.raw);
        }

  container.setAttribute("id", "searchBoxContainer");
        container.appendChild(this.searchBox);

        let bingApiKey = context.parameters.bingapikey.raw;
        let scriptUrl = "https://www.bing.com/api/maps/mapcontrol?callback=loadAutoSuggest&key=" + bingApiKey;

        let scriptNode = document.createElement("script");
        scriptNode.setAttribute("type", "text/javascript");
  scriptNode.setAttribute("src", scriptUrl);
  // scriptNode.setAttribute("async", "");
  // scriptNode.setAttribute("defer", "");

        document.head.appendChild(scriptNode);
        var _this = this;
        window.setTimeout(() => {

   Microsoft.Maps.loadModule('Microsoft.Maps.AutoSuggest', {
    callback: () => {
                    var options = {maxResults: 5};
                    var manager = new Microsoft.Maps.AutosuggestManager(options);
                    manager.attachAutosuggest('#searchBox', '#searchBoxContainer', (suggestionResult) => {

                        _this.street = suggestionResult.address.addressLine;
                        _this.city = suggestionResult.address.locality;
                        _this.county = suggestionResult.address.district;
                        _this.state = suggestionResult.address.adminDistrict;
                        _this.country = suggestionResult.address.countryRegion;
                        _this.zipcode = suggestionResult.address.postalCode;
                        
                        _this.value = suggestionResult.formattedSuggestion || "";
                        _this.notifyOutputChanged();
                    });
                },
    errorCallback: () =>{alert("Error with loading of module Microsoft.Maps.AutoSuggest.");}
   });
   

        },
            1000);
 }

 private selectedSuggestion(suggestionResult: Microsoft.Maps.ISuggestionResult): void {
  
  alert(suggestionResult.formattedSuggestion);

  this.value = "";
  this.street = "";
  this.city = "";
  this.county = "";
  this.state = "";
  this.country = "";
  this.zipcode = "";
  
  this.value = suggestionResult.formattedSuggestion || "";
  this.notifyOutputChanged();
 }

    private onMouseEnter(): void {
        this.searchBox.className = "addressAutocompleteFocused";
    }

    private onMouseLeave(): void {
        this.searchBox.className = "addressAutocomplete";
    }


 /**
  * Called when any value in the property bag has changed. This includes field values, data-sets, 
         * global values such as container height and width, 
         * offline status, control metadata values such as label, visible, etc.
  * @param context The entire property bag available to control via Context Object; 
         * It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions
  */
    public updateView(context: ComponentFramework.Context<IInputs>): void {
        // Add code to update control view
    }

 /** 
  * It is called by the framework prior to a control receiving new data. 
  * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as “bound” or “output”
  */
    public getOutputs(): IOutputs {
        return {
            value: this.value,
            street: this.street,
            city: this.city,
            county: this.county,
            state: this.state,
            country: this.country,
            zipcode: this.zipcode
        };
    }

 /** 
  * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup.
  * i.e. cancelling any pending remote calls, removing listeners, etc.
  */
    public destroy(): void {
        // Add code to cleanup control if necessary
    }
}

Source Code & Download

https://github.com/acieslik/PCF.BingAddressAutocomplete

Original Post https://code2life.blogspot.com/2019/11/yet-another-address-autocomplete-pcf.html

0 Votes: 0 Upvotes, 0 Downvotes (0 Points)

Leave a reply

Join Us
  • X Network2.1K
  • LinkedIn3.8k
  • Bluesky0.5K
Support The Site
Events
April 2025
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30     
« Mar   May »
Follow
Sign In/Sign Up Sidebar Search
Popular Now
Loading

Signing-in 3 seconds...

Signing-up 3 seconds...