Neo's Personal Matrix

    @bpost/bp-address-auto-complete-by-component
    TypeScript icon, indicating that this package has built-in type declarations

    1.1.5 • Public • Published

    LibAddressAutocompleteByComponent

    This library was generated with Angular CLI version 9.1.9.

    Here under, we provide for ome basic information. But this version of the library is also shipped with a tutorial where you can find some code and some videos. Look at the distribution's 'tutorial' directory.

    Installation of the library

    First install the library:

    npm i --save @bpost/bp-address-auto-complete-by-component

    Install some dependencies

    The library only has one dependency to a translation tool ngx-translate. Intall that dependency by the following:

    npm i --save @ngx-translate/core

    npm i --save ngx-translate-multi-http-loader

    Tutorial

    In the distribution, we have added a tutorial to help developers integrate our widget. You will find some source code (an angular application) and some references to videos, listed in the file tutorial/tutorial-videos.txt. Videos are published at youtube.com.

    Pre requisites: Have nodeJS and Angular installed

    You first need to have nodeJS and Angular installed. installing angular:

    npm i -g @angular/cli

    Installation of the library

    First install the library:

    npm i --save @bpost/bp-address-auto-complete-by-component

    Install some dependencies

    The library only has one dependency to a translation tool ngx-translate. Intall that dependency by the following:

    npm i --save @ngx-translate/core
    
    npm i --save ngx-translate-multi-http-loader
    

    Integrate the library in your application ng module

    After you have installed the library and its dependencies, you have to declare the libray and the translation module in your application. Typically, you do that in your app.module.ts file. Here is a possible solution:

    app.module.ts:
    
    import { BrowserModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { NgModule } from '@angular/core';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { CommonModule } from '@angular/common';
    import { HttpClient, HttpClientModule } from '@angular/common/http';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    
    import { LibAddressAutocompleteByComponentModule } from '@bpost/bp-address-auto-complete-by-component';
    import { MultiTranslateHttpLoader } from 'ngx-translate-multi-http-loader';
    import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
    
    
    export function HttpLoaderFactory(http: HttpClient) {                   // <------
    // const i18nResourcePath = environment.i18nResourcePath;
    return new MultiTranslateHttpLoader(http, [
        {prefix: './assets/i18n/', suffix: '.json'},
        {prefix: './assets/aacwidget/i18n/', suffix: '.json'}
        // {prefix: /*'./shared/assets/i18n/'*/ i18nResourcePath, suffix: '.json'},
    ]);
    }
    
    @NgModule({
    declarations: [
        AppComponent,
    ],
    imports: [
        CommonModule,
        BrowserModule,
        BrowserAnimationsModule,
        HttpClientModule,
        FormsModule,
        ReactiveFormsModule,
    
        TranslateModule.forRoot({               // <------
        defaultLanguage: 'en',
        loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
        }
        }),
    
        LibAddressAutocompleteByComponentModule,  // <------
        AppRoutingModule
    ],
    providers: [],
    bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    Using the MultiTranslateHttpLoader allows you to load the needed resources for the widget, but also the resources needed for your application in case of you are also using the same translation tool.

    Copy the resources needed by the widget

    After your have included the widget declaration in your ng module, you also need to add the resources also shipped with the distribution. You can find these resources in the following location:

    <your_root_dir>/node_modules/@bpost/bp-address-auto-complete-by-component/resources.
    

    Under that directory, you will find an 'assets' dir. Copy the content of that directory to your resources dir. For an angular project, you copy these resources under your 'assets' dir, and as a result, these resources are structured like this:

    <your_root_dir>/src/assets/aacwidget
    

    This is the default resource location also used by the MultiTranslateHttpLoader configured in your app.module.ts file (NgModule). You can change these default locations as you want.

    Notice the assets/aacwidget resources contains 2 sub-directories:

    • i18n, used by the translation tool, ngx-translate
    • scss, for styling

    The styling files have to be added to your project too. The <your_root_dir>/src/assets/aacwidget/scss directory contains 2 files:

    • aacwidget-default.scss
    • aacwidget-custom.scss

    The first file, even named as .scss, contains pure css style instructions, while the other is used for some kind of responsive informations and is using scss format.

    A common way to do that is by adding the declaration of these file in the <your_root_dir>/src/style.scss (or <your_root_dir>/src/style.css) file of your project. If your project is using pure css, do not include the file 'aacwidget-custom.scss'.

    So your style.scss file content can look like this:

    style.scss:
    /* You can add global styles to this file, and also import other style files */
    
    @import 'assets/aacwidget/scss/aacwidget-default.scss';
    @import 'assets/aacwidget/scss/aacwidget-custom.scss';
    

    You can customize the rendering of the widget by just create a new css file where you override the default styles. Don't forget to add it after the default css import.

    Integrating the widget in your application

    Suppose you have created a new component in your application, called 'widget'. If you have used the angular cli to created it, you should have generated 4 files, maybe like this:

    • widget.component.html
    • widget.component.scss
    • widget.component.spec.ts
    • widget.component.ts

    Most of the work to integrate the bpost widget will be done in the 'widget.component.html' and 'widget.component.ts' files. The tutorial is giving 2 examples of integration:

    • a small integration with a few features: widget-simple component
    • a full integration with all features explained: widget-full component.

    Here we will give only the simple elements. PLease refer to the tutorial for more details. Videos are also explaining lot of features.

    Integrating the widget - html

    The html code of your component can look like this:

    widget-simple.component.html
    
    <button type="button" (click)="onSelectLanguage('fr')">FR</button>
    &nbsp;
    <button type="button" (click)="onSelectLanguage('nl')">NL</button>
    &nbsp;
    <button type="button" (click)="onSelectLanguage('en')">EN</button>
    &nbsp;
    <button type="button" (click)="onSelectLanguage('de')">DE</button>
    &nbsp;
    <button type="button" (click)="onSelectLanguage('browser')">Browser</button>
    
    <bp-lib-address-autocomplete-by-component
        [defaultLang]="defaultLanguage"
        [inputLang]="selectedLanguage"
        (addressCompleteEventEmitter)="onAddressComplete($event)"
        (clearInputEventEmitter)="onClearInputEventMessage($event)"
        (validationMessageEventEmitter)="onAddressValidationMessage($event)"
    ></bp-lib-address-autocomplete-by-component>
    

    In this code, we illustrate the following features:

    • the default language used at application startup
    • the language used by the user if the application is multilingual
    • the capture of the 'address complete' event from the widget
    • the capture of the 'clear input' event from the widget
    • the capture of the 'validation' event from the widget

    Integrating the widget - Coding

    The code of your compoent can look lke this:

    widget-simple.component.ts
    
    import { Component, OnInit } from '@angular/core';
    import { TranslateService } from '@ngx-translate/core';
    
    @Component({
    selector: 'app-widget-simple',
    templateUrl: './widget-simple.component.html',
    styleUrls: ['./widget-simple.component.scss']
    })
    export class WidgetSimpleComponent implements OnInit {
    
        defaultLanguage = 'en';
        selectedLanguage: string;
    
        constructor(
            private translate: TranslateService,
        ) { }
    
        ngOnInit(): void {
        }
    
        onAddressComplete(event)
        {
            console.log('address complete event message', event);
        }
    
        onClearInputEventMessage(event)
        {
            console.log('address clear input message', event);
        }
    
        onAddressValidationMessage(event)
        {
            console.log('address system message', event);
        }
    
        onSelectLanguage(lang: string)
        {
            if (lang === 'browser') {
                const browserLang = this.translate.getBrowserLang();
                this.translate.use(browserLang);
                this.selectedLanguage = browserLang;
            } else {
                this.translate.use(lang);
                this.selectedLanguage = lang;
            }
    
        }
    }
    

    The most important event handler is the 'onAddressComplete'. Each time an element of the address is modified by the user, an event is emitted. You will have to parse the message and then decide what to do in each case. The content of the message can be interpreted in 3 majors ways:

    • The address is NOT recognized (still not correct nor validated) because at least an element is missing (locality, street, number, box)
    • the address is correct and recognized
    • the address is (seems) correct but is NOT recognized

    The 'onClearInputEventMessage' handler is receiving a message when the user is clearing an element of the address, by using the 'cross' indicator available in each element. The message contains the name of the cleared element. For instance: 'STREET_NUMBER'. This is part of an enumeration: 'LOCALITY', 'STREET', 'STREET_NUMBER', 'BOX_NUMBER'.

    The 'onAddressValidationMessage' handler is in fact receiving a message when something goes wrong. It thus concerns a message about the 'addressvalidation' process itself, running on the backend. As each element has its own service (see the widget-full component), if one of these services is having some trouble, the system will fail and returns a message telling the system was not able to evaluate the address. The message can look like this:

    {
        messageType: "service-unavailable"
        translatedMessage: "service-unavailable"
    }
    
    or: (translated in 'fr'):
    
    {
        messageType: "service-unavailable"
        translatedMessage: "Le service n'est pas disponible, veuillez réessayer plus tard."
    }
    

    The translatedMessage is given regarding the resources and the currently used language by the widget. (see assets/aacwidget/i18n files)

    Message for event onAddressComplete - Address not recognized

    In that case, an element of the address is still missing. The content of the event returned by the system is different for each 'missing' element.

    If you just selected the locality (or postal code), the message can look like this:

    {
        detectedLanguage: "fr"
        isComplete: false
        localityName: "Neufvilles"
        municipalityName: "SOIGNIES"
        postalCode: "7063"
        searchBarString: "7063 Neufvilles"
        string: "7063 Neufvilles"
    }
    

    If you selected the street, the message can look like this:

    {
        detectedLanguage: "fr"
        isComplete: false
        localityName: "NEUFVILLES"
        municipalityName: "SOIGNIES"
        postalCode: "7063"
        searchBarString: "RUE RAMÉE"
        streetName: "RUE RAMÉE"
        string: "RUE RAMÉE"
    }
    

    If you selected the number (street number), the message can look like this (): (): In this case this means your need to provide for a box number.

    {
        detectedLanguage: "nl"
        houseNumber: "21"
        isComplete: false
        latitude: 51.154121
        localityName: "WILRIJK"
        longitude: 4.391701
        municipalityName: "ANTWERPEN"
        postalCode: "2610"
        searchBarString: "21"
        streetName: "VOLKERENLAAN"
        string: "21"
    }
    

    For each of these 3 messages, you can see the 'isComplete' attribute is on 'false': isComplete: false. This indicates the address is (still) not recognized.

    Message for event onAddressComplete - Address correct and recognized

    Here the user has entered enough element so that the system could recognized the address. In that case the message can look like this:

    {
        boxNumber: "5"
        detectedLanguage: "nl"
        houseNumber: "21"
        isComplete: true
        isCompleteNotificationDone: true
        latitude: 51.154121
        localityName: "WILRIJK"
        longitude: 4.391701
        municipalityName: "ANTWERPEN"
        postalCode: "2610"
        searchBarString: "5"
        streetName: "VOLKERENLAAN"
        string: "5"
    }
    

    In this case, the attribute 'isComplete' is on 'true': isComplete: true, and the attribute 'isCompleteNotificationDone' too: isCompleteNotificationDone: true. This indicates the address is recognized.

    Message for event onAddressComplete - address (seems) correct but is NOT recognized

    Here the user has entered enough elements, but at least has used the option 'not in list' for the street number and/or the box number. In that case the system will tell the address is accepted but conditionally regarding the 'not in list' option has been used. In that case the message returned by the system can look like this:

    {
        boxNumber: "24"
        detectedLanguage: "nl"
        houseNumber: "21"
        isComplete: true
        isCompleteNotificationDone: true
        latitude: 51.154121
        localityName: "WILRIJK"
        longitude: 4.391701
        municipalityName: "ANTWERPEN"
        not-in-list: true
        postalCode: "2610"
        searchBarString: "24"
        streetName: "VOLKERENLAAN"
        string: "24"
    }
    

    As you can see, the attribute 'isComplete' is on 'true': isComplete: true, and the attribute 'isCompleteNotificationDone' too: isCompleteNotificationDone: true, BUT !!! Another attribute is present in the message: not-in-list: true.

    The 'not in list' feature

    The 'not in list' feature is used to allow the user to indicate a street number or a box number is not provided in the dropdown list constructed by data coming from the backend. This 'not in list' feature is allowed by default. Of course, you can disable it by just giving an attribute to the widget.

    In your html:

    <bp-lib-address-autocomplete-by-component
        .....
        [notInListAllowed]="notInListAllowed"
        .....
    

    In your component:

    // The 'not in list' feature, if allowed, is only available for the street number and box number address element
    // By default, that feature is allowed.
    notInListAllowed = false;
    

    With this in place, the 'not in list' feature is disabled.

    Pre-filling the widget

    Its possible to pre-fill the widget before validating an address. In this version (i.e. 1.0.9) we introduced a new parameter: onFocusShowSuggestionsAfterPrefill, and we have removed the support for 'unstructured' addresses. The prefill structure is now like this:

    this.prefilledParameters = new PrefilledParameters(
      {
        municipalityName: 'Wilrijk',
        postalCode: '2610',
        streetName: 'volklorenlaan',
        streetNumber: '',
        boxNumber: '',
    
        state: true
    
        onFocusShowSuggestionsAfterPrefill = false;
      }
    );
    this.minLevel = this.prefilledParameters.minLevel;
    

    In that case, as you can see, you have to define 2 fields in your component like this:

    minLevel: number; prefilledParameters: PrefilledParameters;

    Where the PrefilledParameters is imported from the library:

    import { PrefilledParameters } from '@bpost/bp-address-auto-complete-by-component';
    

    And in the html, you have to provide these fields to the widget:

    <bp-lib-address-autocomplete-by-component
        ......
        [minLevel]="minLevel"
        [addressParams]="prefilledParameters"
        .....
    

    The role of the parameter 'onFocusShowSuggestionsAfterPrefill' is to indicate if you want to immediately show the drop down containing the suggestion for a particular address field when one address field got the focus. If that option is on 'false' (the default), when the user set the focus on that field for the first time the suggestions are not shown. The suggestions will only be shown if the user modifies the content of the field, or if the field receives the focus for the second time. So suppose you have prefilled the postal code, the locality, the street and the street number. if the user put the cursor in the street field, nothing will happen. If he puts the cursor in the street number field, nothing will happen. But if the user comes back in the street field, as it is the second times the field receives the focus, the drop down containing the suggestion will be shown, of course only if the system has found some suggestions. This behaviour is valid for each address field independently.

    Customizing the component

    Your can override some css styles by providing and loading your own css. The aacwidget-default.scss style sheet should not be modified. Just override the styles you want in the custom scss.

    You can also customize the content of the labels of the widget. For instance, the english label and placeholder for the 'street' element of the component are: label: 'street name' placeholder: Provide a streetName...

    The label and placeholder are given in the ./assets/aacwidget/i18n directory, where you should have put some translation files. Actually we have provided for 4 languages: de, en, fr and nl. Of course, you can add as many language as you want.

    Labels can be found at the beginning of each translation files. Here is the default content for en.json:

    	"label": {
    		"boxNumber": "box number",
    		"streetNumber": "house number",
    		"municipalityName": "municipality",
    		"postalCode": "postal code",
    		"streetName": "street name"
    	}
    

    And for the placehoder, you can find the corresponding placeholder default at the corresponding address part. For the street name, in the en.json file:

        "street": {
            "placeholder": {
                "input-placeholder": "Provide a streetName..."
            },
            "suggestion": {
                "message": {
                    "subl": "<em>{{sub}}</em> is a sub-municipality of <em>{{principal}}</em>"
                }
            }
        },
    

    Its also at that place you can customize the message given in the suggestion list. But take care! The {{sub}} and {{principal}} are variable placeholders used to format the message.

    Demo application

    To facilitate the integration of this widget, we also have created a demo application shipped with its source code. That demo application is available from npm:

    npm i @bpost/bp-address-auto-complete-by-component-demo-application
    

    Just take the bp-address-auto-complete-by-component-demo-application.zip file, uncompress it and launch the application:

    ng serve -o
    

    The source code of the demo application can also be found under the 'demo' sub-directory of this distribution

    To help windows users to install the demo application, we also provide for a script (batch) file which will install and run the demo application automatically. Just execute: install-and-start-demo.bat, in an empty directory. The installer will create a 'demo' sub-directory, in which you will find the file 'run-demo.bat' you can execute if you want to run the demo again after having closed it.

    For your facility, the current distribution contains a file 'install-and-start-demo.bat' which will install and run the demo application automacally.

    Online Documentation

    Online documentation is also avalable at the following url:

    https://www.bpost.be/site/en/address/

    Contact us

    If you have any question you can send an email to the following address:

    EMail: adres@bpost.be

    License

    License

    Copyright (c) 2016 Bpost and other contributors

    Licensed under the MIT License

    Keywords

    none

    Install

    npm i @bpost/bp-address-auto-complete-by-component

    DownloadsWeekly Downloads

    87

    Version

    1.1.5

    License

    none

    Unpacked Size

    2.24 MB

    Total Files

    71

    Last publish

    Collaborators

    • u266996
    • kevin_dsouza04
    • bpost_licences
    • wim_rosseel
    • u514567
    • u530539
    • jijo.george
    • kaising