projects/common/lib/components/street/street.component.ts
selector | common-street |
templateUrl | ./street.component.html |
Properties |
|
Methods |
|
Inputs |
Outputs |
Accessors |
constructor(controlDir: NgControl, geocoderService: GeocoderService)
|
|||||||||
Parameters :
|
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
|
|
Defined in
AbstractFormControl:16
|
errorMessage | |
Type : ErrorMessage
|
|
Inherited from
AbstractFormControl
|
|
Defined in
AbstractFormControl:19
|
label | |
Type : string
|
|
Inherited from
AbstractFormControl
|
|
Defined in
AbstractFormControl:14
|
blur | |
Type : EventEmitter<any>
|
|
select | |
Type : EventEmitter<GeoAddressResult>
|
|
valueChange | |
Type : EventEmitter<string>
|
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onBlur | ||||||
onBlur(event: any)
|
||||||
Parameters :
Returns :
void
|
onError |
onError()
|
Returns :
Observable<GeoAddressResult[]>
|
onKeyUp | ||||||
onKeyUp(event: KeyboardEvent)
|
||||||
Parameters :
Returns :
void
|
onSelect | ||||||
onSelect(event: TypeaheadMatch)
|
||||||
Parameters :
Returns :
void
|
onValueChange | ||||||
onValueChange(value: any)
|
||||||
Parameters :
Returns :
void
|
writeValue | ||||||
writeValue(value: any)
|
||||||
Parameters :
Returns :
void
|
ngOnInit |
ngOnInit()
|
Inherited from
AbstractFormControl
|
Defined in
AbstractFormControl:27
|
Returns :
void
|
registerOnChange | ||||||
registerOnChange(fn: any)
|
||||||
Inherited from
AbstractFormControl
|
||||||
Defined in
AbstractFormControl:35
|
||||||
Parameters :
Returns :
void
|
registerOnTouched | ||||||
registerOnTouched(fn: any)
|
||||||
Inherited from
AbstractFormControl
|
||||||
Defined in
AbstractFormControl:40
|
||||||
Parameters :
Returns :
void
|
Protected registerValidation | ||||||||||||
registerValidation(ngControl: NgControl, fn: ValidationErrors)
|
||||||||||||
Inherited from
AbstractFormControl
|
||||||||||||
Defined in
AbstractFormControl:68
|
||||||||||||
Register self validating method
Parameters :
Returns :
any
|
setDisabledState | ||||||
setDisabledState(isDisabled: boolean)
|
||||||
Inherited from
AbstractFormControl
|
||||||
Defined in
AbstractFormControl:45
|
||||||
Parameters :
Returns :
void
|
Protected setErrorMsg |
setErrorMsg()
|
Inherited from
AbstractFormControl
|
Defined in
AbstractFormControl:49
|
Returns :
void
|
Private validateLabel |
validateLabel()
|
Inherited from
AbstractFormControl
|
Defined in
AbstractFormControl:88
|
Returns :
void
|
Abstract writeValue | ||||||
writeValue(value: any)
|
||||||
Inherited from
AbstractFormControl
|
||||||
Defined in
AbstractFormControl:32
|
||||||
Parameters :
Returns :
void
|
_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()
|
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
|
Defined in
AbstractFormControl:11
|
_onChange |
Default value : () => {...}
|
Inherited from
AbstractFormControl
|
Defined in
AbstractFormControl:23
|
_onTouched |
Default value : () => {...}
|
Inherited from
AbstractFormControl
|
Defined in
AbstractFormControl:24
|
Public objectId |
Type : string
|
Default value : UUID.UUID()
|
Inherited from
Base
|
Defined in
Base:11
|
An identifier for parents to keep track of components |
value | ||||||
getvalue()
|
||||||
setvalue(val: string)
|
||||||
Parameters :
Returns :
void
|
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>