UNPKG

ngx-autocom-place

Version:

Angular GoogleMaps Places Api Autocomplete Directive

236 lines (229 loc) 11.4 kB
import { __awaiter } from 'tslib'; import { Injectable, EventEmitter, Directive, ElementRef, Output, Input, NgModule } from '@angular/core'; import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; class NgxAutocomPlaceService { constructor() { this.autocompleteService = new google.maps.places.AutocompleteService(); this.placeService = new google.maps.places.PlacesService(document.createElement('div')); } getPredictions(value, options) { if (!this.sessionToken) { this.sessionToken = new google.maps.places.AutocompleteSessionToken(); } const request = Object.assign({ input: value, sessionToken: this.sessionToken }, options); return new Promise((resolve, reject) => { this.autocompleteService.getPlacePredictions(request, (results, status) => { if (status !== google.maps.places.PlacesServiceStatus.OK && status !== google.maps.places.PlacesServiceStatus.ZERO_RESULTS) { reject(status); return; } else { resolve(results); } }); }); } getPlaceDetails(placeId) { return new Promise((resolve, reject) => { this.placeService.getDetails({ placeId, sessionToken: this.sessionToken, }, (result, status) => { this.sessionToken = null; if (status !== google.maps.places.PlacesServiceStatus.OK) { reject(status); return; } resolve(result); }); }); } } NgxAutocomPlaceService.decorators = [ { type: Injectable } ]; NgxAutocomPlaceService.ctorParameters = () => []; class NgxAutocomPlaceDirective { constructor(el, ngxAutocomplaceService) { this.el = el; this.ngxAutocomplaceService = ngxAutocomplaceService; this.points = []; this.selectedPlace = new EventEmitter(); this.predictions = new EventEmitter(); this.options = { types: ["geocode"] // 'establishment' / 'address' / 'geocode' }; this.handleEnterKeydown = true; this.hideResultDropdown = false; this.debounceTime = 150; this.downArrowIndex = -1; } ; ngOnInit() { return __awaiter(this, void 0, void 0, function* () { if (this.el.nativeElement instanceof HTMLInputElement) { this.inputElement = this.el.nativeElement; } else if (this.el.nativeElement.tagName === 'ION-INPUT') { this.inputElement = yield this.el.nativeElement.getInputElement(); } else if (this.el.nativeElement.tagName === 'ION-SEARCHBAR') { this.inputElement = yield this.el.nativeElement.getInputElement(); } else { return; } const styles = document.createElement('style'); styles.innerHTML = `@keyframes beginBrowserAutofill{0%{}to{}}@keyframes endBrowserAutofill{0%{}to{}}.pac-container{background-color:#fff;position:absolute!important;z-index:1000;border-radius:2px;border-top:1px solid #d9d9d9;font-family:Arial,sans-serif;box-shadow:0 2px 6px rgba(0,0,0,0.3);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}.pac-logo:after{content:"";padding:1px 1px 1px 0;height:18px;box-sizing:border-box;text-align:right;display:block;background-image:url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3.png);background-position:right;background-repeat:no-repeat;background-size:120px 14px}.hdpi.pac-logo:after{background-image:url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3_hdpi.png)}.pac-item{cursor:default;padding:0 4px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;line-height:30px;text-align:left;border-top:1px solid #e6e6e6;font-size:11px;color:#999}.pac-item:hover{background-color:#fafafa}.pac-item-selected,.pac-item-selected:hover{background-color:#ebf2fe}.pac-matched{font-weight:700}.pac-item-query{font-size:13px;padding-right:3px;color:#000}.pac-icon{width:15px;height:20px;margin-right:7px;margin-top:6px;display:inline-block;vertical-align:top;background-image:url(https://maps.gstatic.com/mapfiles/api-3/images/autocomplete-icons.png);background-size:34px}.hdpi .pac-icon{background-image:url(https://maps.gstatic.com/mapfiles/api-3/images/autocomplete-icons_hdpi.png)}.pac-icon-search{background-position:-1px -1px}.pac-item-selected .pac-icon-search{background-position:-18px -1px}.pac-icon-marker{background-position:-1px -161px}.pac-item-selected .pac-icon-marker{background-position:-18px -161px}.pac-placeholder{color:gray}.pac-target-input:-webkit-autofill{animation-name:beginBrowserAutofill}.pac-target-input:not(:-webkit-autofill){animation-name:endBrowserAutofill}`; var ref = document.querySelector('script'); ref.parentNode.insertBefore(styles, ref); this.inputElement.addEventListener('blur', () => { this.blurEvent(); }); this.inputSubscription = fromEvent(this.inputElement, 'input').pipe(debounceTime(this.debounceTime)).subscribe((_e) => { this.inputEvent(_e); }); this.inputElement.addEventListener('keydown', (e) => { this.keydownEvent(e); }); }); } createPacContainer(input, results) { this.resultPacContainer = document.createElement('div'); const inputRect = input.getBoundingClientRect(); this.resultPacContainer.classList.add('pac-container', 'pac-logo', 'hdpi'); this.resultPacContainer.style.position = 'absolute'; this.resultPacContainer.style.top = inputRect.bottom + 'px'; this.resultPacContainer.style.left = inputRect.left + 'px'; this.resultPacContainer.style.width = (inputRect.right - inputRect.left) + 'px'; results.forEach(element => { this.resultPacContainer.appendChild(this.createPacItem(element.place_id, element.structured_formatting.main_text, element.structured_formatting.secondary_text, element.structured_formatting.main_text_matched_substrings[0].length)); }); document.querySelector('body').appendChild(this.resultPacContainer); } createPacItem(placeId, mainText, secondaryText, matchMainOffset) { const item = document.createElement('div'); item.classList.add('pac-item'); item.id = placeId; const spanIcon = document.createElement('span'); spanIcon.classList.add('pac-icon', 'pac-icon-marker'); const spanContentMatch = document.createElement('span'); spanContentMatch.classList.add('pac-item-query'); const spanContentMatched = document.createElement('span'); spanContentMatched.classList.add('pac-matched'); spanContentMatched.innerText = mainText.substr(0, matchMainOffset); spanContentMatch.appendChild(spanContentMatched); spanContentMatch.appendChild(document.createTextNode(mainText.substr(matchMainOffset))); const spanCity = document.createElement('span'); spanCity.appendChild(document.createTextNode(secondaryText)); item.appendChild(spanIcon); item.appendChild(spanContentMatch); item.appendChild(spanCity); item.addEventListener('click', () => { this.getPlaceDetails(placeId); }); return item; } getPlaceDetails(placeId) { this.ngxAutocomplaceService.getPlaceDetails(placeId).then((result) => { // this.inputElement.value = result.formatted_address; // this.inputElement.blur(); this.selectedPlace.emit(result); }); } blurEvent() { setTimeout(() => { if (this.resultPacContainer) { this.removePacItems(); } }, 250); } inputEvent(_e) { if (this.inputElement && this.inputElement.value) { this.ngxAutocomplaceService.getPredictions(this.inputElement.value, this.options).then((results) => { this.removePacItems(); if (results) { if (!this.hideResultDropdown) { this.results = results; this.createPacContainer(this.inputElement, results); } this.predictions.emit(results); } }); } else { this.removePacItems(); } } keydownEvent(e) { var _a, _b; if (this.handleEnterKeydown) { if (e.key === 'Enter' || e.keyCode === 13) { if (this.results && this.results.length > 0) { this.getPlaceDetails(this.results[this.downArrowIndex > -1 ? this.downArrowIndex : 0].place_id); this.removePacItems(); } } } if (e.keyCode === 40) { this.downArrowIndex++; if (this.downArrowIndex > 0) { (_a = document.querySelectorAll('.pac-item')[this.downArrowIndex - 1]) === null || _a === void 0 ? void 0 : _a.classList.remove('pac-item-selected'); } (_b = document.querySelectorAll('.pac-item')[this.downArrowIndex]) === null || _b === void 0 ? void 0 : _b.classList.add('pac-item-selected'); } } removePacItems() { if (this.resultPacContainer) { this.resultPacContainer.remove(); this.resultPacContainer = null; } this.downArrowIndex = -1; ; } ngOnDestroy() { this.inputElement.removeEventListener('blur', () => { this.blurEvent(); }); this.inputSubscription.unsubscribe(); this.inputElement.removeEventListener('keydown', (e) => { this.keydownEvent(e); }); } } NgxAutocomPlaceDirective.decorators = [ { type: Directive, args: [{ selector: '[ngxAutocomPlace]' },] } ]; NgxAutocomPlaceDirective.ctorParameters = () => [ { type: ElementRef }, { type: NgxAutocomPlaceService } ]; NgxAutocomPlaceDirective.propDecorators = { selectedPlace: [{ type: Output }], predictions: [{ type: Output }], options: [{ type: Input }], handleEnterKeydown: [{ type: Input }], hideResultDropdown: [{ type: Input }], debounceTime: [{ type: Input }] }; class NgxAutocomPlaceModule { } NgxAutocomPlaceModule.decorators = [ { type: NgModule, args: [{ imports: [], declarations: [NgxAutocomPlaceDirective], exports: [NgxAutocomPlaceDirective], providers: [NgxAutocomPlaceService] },] } ]; /* * Public API Surface of ngx-autocom-place */ /** * Generated bundle index. Do not edit. */ export { NgxAutocomPlaceDirective, NgxAutocomPlaceModule, NgxAutocomPlaceService as ɵa }; //# sourceMappingURL=ngx-autocom-place.js.map