File

projects/common/lib/components/street/street.component.ts

Extends

AbstractFormControl

Implements

OnInit

Metadata

selector common-street
templateUrl ./street.component.html

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(controlDir: NgControl, geocoderService: GeocoderService)
Parameters :
Name Type Optional
controlDir NgControl No
geocoderService GeocoderService No

Inputs

label
Type : string
Default value : 'Full street address or rural route'
labelforId
Type : string
Default value : 'street_' + this.objectId
maxlength
Type : string
Default value : '250'
placeholder
Type : string
Default value : 'Street name'
required
Type : boolean
Default value : false
useGeoCoder
Type : boolean
Default value : false
value
Type : string
disabled
Type : boolean
Default value : false
Inherited from AbstractFormControl
errorMessage
Type : ErrorMessage
Inherited from AbstractFormControl
label
Type : string
Inherited from AbstractFormControl

Outputs

blur
Type : EventEmitter<any>
select
Type : EventEmitter<GeoAddressResult>
valueChange
Type : EventEmitter<string>

Methods

ngOnInit
ngOnInit()
Returns : void
onBlur
onBlur(event: any)
Parameters :
Name Type Optional
event any No
Returns : void
onError
onError()
onKeyUp
onKeyUp(event: KeyboardEvent)
Parameters :
Name Type Optional
event KeyboardEvent No
Returns : void
onSelect
onSelect(event: TypeaheadMatch)
Parameters :
Name Type Optional
event TypeaheadMatch No
Returns : void
onValueChange
onValueChange(value: any)
Parameters :
Name Type Optional
value any No
Returns : void
writeValue
writeValue(value: any)
Parameters :
Name Type Optional
value any No
Returns : void
ngOnInit
ngOnInit()
Inherited from AbstractFormControl
Returns : void
registerOnChange
registerOnChange(fn: any)
Inherited from AbstractFormControl
Parameters :
Name Type Optional
fn any No
Returns : void
registerOnTouched
registerOnTouched(fn: any)
Inherited from AbstractFormControl
Parameters :
Name Type Optional
fn any No
Returns : void
Protected registerValidation
registerValidation(ngControl: NgControl, fn: ValidationErrors)
Inherited from AbstractFormControl

Register self validating method

Parameters :
Name Type Optional Description
ngControl NgControl No
fn ValidationErrors No

function for validating self

Returns : any
setDisabledState
setDisabledState(isDisabled: boolean)
Inherited from AbstractFormControl
Parameters :
Name Type Optional
isDisabled boolean No
Returns : void
Protected setErrorMsg
setErrorMsg()
Inherited from AbstractFormControl
Returns : void
Private validateLabel
validateLabel()
Inherited from AbstractFormControl
Returns : void
Abstract writeValue
writeValue(value: any)
Inherited from AbstractFormControl
Parameters :
Name Type Optional
value any No
Returns : void

Properties

_defaultErrMsg
Type : ErrorMessage
Default value : { required: LabelReplacementTag + ' is required.', invalidChar: LabelReplacementTag + ' must contain letters, and numbers and may include special characters such as hyphen, ' + 'period, apostrophe, number sign, ampersand and blank characters.' }
Public controlDir
Type : NgControl
Decorators :
@Optional()
@Self()
Private search
Type : string

Search string to store result from GeoCoder request

Private searchText$
Default value : new Subject<string>()

The subject that triggers on user text input and gets typeaheadList$ to update.

street
Type : string
Default value : ''
typeaheadList$
Type : Observable<GeoAddressResult[]>

The list of results, from API, that is passed to the typeahead list Result from GeoCoderService address lookup

Abstract _defaultErrMsg
Type : ErrorMessage
Default value : {}
Inherited from AbstractFormControl
_onChange
Default value : () => {...}
Inherited from AbstractFormControl
_onTouched
Default value : () => {...}
Inherited from AbstractFormControl
Public objectId
Type : string
Default value : UUID.UUID()
Inherited from Base
Defined in Base:11

An identifier for parents to keep track of components

Accessors

value
getvalue()
setvalue(val: string)
Parameters :
Name Type Optional
val string No
Returns : void

Design Guidelines

Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente, magnam ipsam. Sit quasi natus architecto rerum unde non provident! Quia nisi facere amet iste mollitia voluptatem non molestias esse optio?

Aperiam fugiat consectetur temporibus, iste repellat, quisquam sapiente nisi distinctio optio, autem nemo tenetur error eum voluptatibus ab accusamus quis voluptatum blanditiis. Quam et ut reprehenderit vitae nobis, at ipsum!

Exercitationem pariatur animi repudiandae corporis obcaecati ratione ducimus beatae quam, nostrum magnam unde numquam quidem cupiditate odit id. Beatae alias molestiae, optio incidunt harum quia voluptates deserunt sequi. Nesciunt, optio.

import { Component, Input, Output, EventEmitter, Optional, Self, OnInit } from '@angular/core';
import { NgControl } from '@angular/forms';
import { Observable, Subject, of } from 'rxjs';
import { GeoAddressResult, GeocoderService } from '../../services/geocoder.service';
import { debounceTime, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators';
import { TypeaheadMatch } from 'ngx-bootstrap/typeahead';
import { AbstractFormControl } from '../../models/abstract-form-control';
import { ErrorMessage, LabelReplacementTag } from '../../models/error-message.interface';
import { CANADA } from '../country/country.component';
import { BRITISH_COLUMBIA } from '../province/province.component';

@Component({
  selector: 'common-street',
  templateUrl: './street.component.html',
})
export class StreetComponent extends AbstractFormControl implements OnInit  {

  @Input() label: string = 'Full street address or rural route';
  @Input() maxlength: string = '250';
  @Input() labelforId: string = 'street_' + this.objectId;
  @Input() useGeoCoder: boolean = false;
  @Input() placeholder: string = 'Street name';
  @Input() required: boolean = false;

  @Input()
  set value( val: string ) {
    if ( val ) {
      this.street = val;
    }
  }
  get value() {
    return this.street;
  }

  @Output() valueChange: EventEmitter<string> = new EventEmitter<string>();
  @Output() blur: EventEmitter<any> = new EventEmitter<any>();
  @Output() select: EventEmitter<GeoAddressResult> = new EventEmitter<GeoAddressResult>();

  street: string = '';

  /**
   * The list of results, from API, that is passed to the typeahead list
   * Result from GeoCoderService address lookup
   */
  typeaheadList$: Observable<GeoAddressResult[]>;

  /** Search string to store result from GeoCoder request */
  private search: string;
  /** The subject that triggers on user text input and gets typeaheadList$ to update.  */
  private searchText$ = new Subject<string>();

  _defaultErrMsg: ErrorMessage = {
    required:  LabelReplacementTag + ' is required.',
    invalidChar: LabelReplacementTag + ' must contain letters, and numbers and may include special characters such as hyphen, ' +
                 'period, apostrophe, number sign, ampersand and blank characters.'
  };


  constructor( @Optional() @Self() public controlDir: NgControl,
               private geocoderService: GeocoderService ) {
    super();
    if ( controlDir ) {
      controlDir.valueAccessor = this;
    }
  }

  ngOnInit() {
    super.ngOnInit();

    // Set up for using GeoCoder
    this.typeaheadList$ = this.searchText$.pipe(
      debounceTime(500),
      distinctUntilChanged(),
      // Trigger the network request, get results
      switchMap(searchPhrase => {
        return this.geocoderService.lookup(searchPhrase);
      }),
      catchError(() => this.onError())
    );
  }

  onValueChange( value: any ) {
    if ( this.useGeoCoder ) {
      // set the search string
      this.search = value;
    }
    this._onChange( value );
    this.valueChange.emit( value );
  }

  onBlur( event: any ) {
    this._onTouched( event );
    this.blur.emit( event );
  }

  writeValue( value: any ): void {
    if ( value !== undefined ) {
        this.street = value;
    }
  }

  // @HostListener('keyup', ['$event'])
  onKeyUp(event: KeyboardEvent): void {
    /**
     * Filter out 'enter' and other similar keyboard events that can trigger
     * when user is selecting a typeahead option instead of entering new text.
     * Without this filter, we do another HTTP request + force disiplay the UI
     * for now reason
     */
    if (event.keyCode === 13 || event.keyCode === 9) {
      // enter & tab
      return;
    }

    this.searchText$.next(this.search);
  }

  onError(): Observable<GeoAddressResult[]> {
    // Empty array simulates no result response, nothing for typeahead to iterate over
    return of([]);
  }

  onSelect(event: TypeaheadMatch): void {
    const data: GeoAddressResult = event.item;
    this.street = data.street;

    // Set to defaults in response
    data.country = CANADA;
    data.province = BRITISH_COLUMBIA;
    this.select.emit( data );
  }

}
<label for="{{labelforId}}">{{label}}</label>
<div *ngIf="useGeoCoder; else NoGeoCoder;">
    <input class="form-control"
           spellcheck="false"
           type="text"
           id="{{labelforId}}"
           [ngModel]="street"
           (ngModelChange)="onValueChange($event)"
           (blur)="onBlur($event)"
           [disabled]="disabled"
           [attr.maxlength]="maxlength"
           [required]="required"
           (keyup)='onKeyUp($event)'
           [typeahead]='typeaheadList$'
           typeaheadOptionField='fullAddress'
           typeaheadMinLength='3'
           (typeaheadOnSelect)="onSelect($event)"
           [placeholder]="placeholder"
           autocomplete="off"/>
</div>

<!-- Error messages for input -->
<common-error-container
[displayError]="controlDir && !disabled && (controlDir.touched || controlDir.dirty) && controlDir.errors">
  <div *ngIf="controlDir.errors?.required">
    {{_defaultErrMsg.required}}
  </div>
  <div *ngIf="controlDir.errors?.invalidChar">
    {{_defaultErrMsg.invalidChar}}
  </div>

</common-error-container>


<ng-template #NoGeoCoder>
  <input class="form-control"
         spellcheck="false"
         type="text"
         id="{{labelforId}}"
         [value]="street"
         (change)="onValueChange($event.target.value)"
         (blur)="onBlur($event)"
         [disabled]="disabled"
         [required]="required"
         [attr.maxlength]="maxlength"
         [placeholder]="placeholder"
         autocomplete="off"/>
</ng-template>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""