I am working on a google map search box. Currently, the search box on organization search is both an address-based search via Google, or a text-based search of our organization database, depending on whether the entered data is a proper address or not. Is there any way that I can separate this into two search boxes with one based on the radius search and the other based on the bound search?
Here is the code that I have(with only one search box):
<div class="map-container">
<div class="sidebar">
<div class="contents sidebar__contents" id="map-search">
<div class="sidebar__inputs">
<input type="text" class="form-control inputs__searchbar" (keydown.enter)="$event.preventDefault()" [value]="searchString ? searchString : ''" [placeholder]="placeholder" #search>
import { Component, Input, Output, OnInit, ViewChild, ElementRef, NgZone } from '@angular/core';
import { MapsAPILoader} from '@agm/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { Organization} from '../organizations/organization';
import { OrganizationService} from '../../services/organization/organization.service';
import constants from '../app.constants';
// import { getResourceByOrganizationId } from '../../../server/api/resource/resource.controller';
// declare var google: any;
@Component({
selector: 'map-search',
template: require('./map-search.html'),
styles: [require('./map-search.scss')],
})
export class MapSearchComponent implements OnInit {
@ViewChild('search', { static: false })
public searchElementRef: ElementRef;
lat: number;
lng: number;
zoom: number;
bounds: google.maps.LatLngBounds;
center: google.maps.LatLngLiteral;
searchBarBounds: google.maps.LatLngBounds;
searchString: string;
place: google.maps.places.PlaceResult;
isAddress: boolean;
queryUrl;
mapQuery;
public noResultsFound: boolean; //TODO: implement html to display when there are no results returned by server
public isCurrentlySearching: boolean; //will allow us to display a loading image when searching
allOrganizations: Organization[] = [];
allMarkers: Marker[] = [];
filterForm: FormGroup;
populationServedOptions: string[];
organizationFocusOptions: string[];
organizationRoleOptions: string[];
filters: {populationServed: string, organizationFocus: string, organizationRole: string};
@Input() inputPopulationServed: string;
//populationServed: string;
@Input() inputOrganizationFocus: string;
//organizationFocus: string;
@Input() inputOrganizationRole: string;
//organizationRole: string;
public filterItems;
public filterItemsSet;
public filterCategories;
queryFilters: Filter[];
activeFilters: Filter[];
isFiltered: boolean;
allFilters: Filter[] = [];
updateResults: boolean;
map: google.maps.Map;
placemarkLayer: google.maps.KmlLayer;
coloradoBounds: google.maps.LatLngBounds;
limit: number; //the number of results per page
offset: number; //offset of results ignored to show the current page requested
numTotalResults: number; //the actual number of results retrieved by search
lastOffset: number;
currentPage: number;
lastPage: number;
static baseValues = {
lat: 39.113014, lng: -105.358887, zoom: 8.0, searchBarBounds: {
east: -104.75481205709076,
north: 39.81839092319901,
south: 39.65998965810583,
west: -105.22568994290924
}
};
static parameters = [MapsAPILoader, NgZone, OrganizationService, Router, ActivatedRoute, FormBuilder];
constructor(
public mapsAPILoader: MapsAPILoader,
private ngZone: NgZone,
private organizationService: OrganizationService,
private router: Router,
private route: ActivatedRoute,
private formBuilder: FormBuilder) {}
public ngOnInit() {
this.lat = MapSearchComponent.baseValues.lat;
this.lng = MapSearchComponent.baseValues.lng;
this.center = { lat: this.lat, lng: this.lng };
this.zoom = MapSearchComponent.baseValues.zoom;
// this.initMap();
this.numTotalResults = 0; //actual number of results returned by search
this.limit = 20; //number of organizations displayed per page
this.offset = 0; //number of results before current list of organizations
this.lastOffset = 0; //last number offset able to be sent to server for a search. Must be a multiple of the limit and less than numTotalResults.
this.currentPage = 1; //current page number
this.lastPage = 1; //last page number able to be viewed
this.populationServedOptions = constants.populationServedOptions;
this.organizationFocusOptions = constants.organizationFocusOptions;
this.organizationRoleOptions = constants.organizationRoleOptions;
this.filterForm = this.formBuilder.group({
selectedPopulationServed: this.populationServedOptions[0],
selectedOrganizationFocus: this.organizationFocusOptions[0],
selectedOrganizationRole: this.organizationRoleOptions[0]
});
this.filters = {populationServed: '', organizationFocus: '', organizationRole: ''};
this.updateResults = false;
this.isAddress = false;
this.placemarkLayer = null;
if(this.route) {
//first get the url/path to determine whether we need to perform simple or advanced search
this.route.url.subscribe(url => {
if(url.length > 1) {
this.queryUrl = url[1].path;
}
if(this.queryUrl === 'search') {
this.route.queryParams
.subscribe(params => {
this.mapQuery = JSON.parse(params.filter);
if (this.mapQuery) {
this.filters = {...this.mapQuery.filters};
this.bounds = {...this.mapQuery.bounds};
this.center = {...this.mapQuery.center};
this.zoom = this.mapQuery.zoom;
this.lat = this.mapQuery.center.lat;
this.lng = this.mapQuery.center.lng;
this.searchString = this.mapQuery.searchString;
this.isAddress = this.mapQuery.isAddress;
this.limit = this.mapQuery.limit;
this.offset = this.mapQuery.offset;
}
}
);
}
});
} else { }
if(this.mapQuery) {
this.isCurrentlySearching = true;
//We then call the method from our OrganizationService that subsequently sends a request to the Organizations API
this.organizationService.searchForOrganizationByLongLat(this.mapQuery).subscribe(
(toReturn: {}) => { //numTotalResults: number, filters: [], kml: string, results: Organization[]
this.allOrganizations = toReturn['results'];
this.allMarkers = this.createMarkers(this.allOrganizations);
this.noResultsFound = (this.allOrganizations.length === 0); //if no results are found,
this.numTotalResults = toReturn['total'];
//highest offset index available for last results
this.lastOffset = Math.floor(this.numTotalResults / this.limit) * this.limit;
//or, total number of pages needed for all results
this.lastPage = Math.ceil(this.numTotalResults / this.limit);
//finds the current page being viewed based on offset. offset and limit should be multiples
this.currentPage = Math.floor(this.offset / this.limit) + 1;
this.isCurrentlySearching = false;
});
}
this.mapsAPILoader.load().then(() => {
let autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement);
autocomplete.setComponentRestrictions({country: 'us'})
this.coloradoBounds = new google.maps.LatLngBounds(
new google.maps.LatLng({ lat: 37, lng: -109 }),
new google.maps.LatLng({ lat: 41, lng: -102 })
);
autocomplete.setBounds(this.coloradoBounds);
autocomplete.addListener('place_changed', () => {
this.ngZone.run(() => {
// get the place result
this.place = autocomplete.getPlace();
// verify result
if (this.place.geometry) {
if (!this.coloradoBounds.contains(this.place.geometry.location)) {
alert('The search location is outside of the bounds of Colorado.');
return;
}
// set latitude, longitude and zoom
this.lat = this.place.geometry.location.lat();
this.lng = this.place.geometry.location.lng();
this.center = { lat: this.lat, lng: this.lng };
this.bounds = this.place.geometry.viewport;
if (this.placemarkLayer != null) {
this.placemarkLayer.setMap(this.map);
}
}
// search term consisting of the search string and flag if it is a searchable address
// tslint:disable-next-line:max-line-length
this.searchString = this.place && this.place.formatted_address ? this.place.formatted_address : this.searchElementRef.nativeElement.value;
if (this.place.formatted_address) {
this.isAddress = true;
this.zoom = 12;
this.mapSearch();
} else {
this.isAddress = false;
if (this.searchString) {
this.verifyAddress();
}
}
// console.log(this.searchString);
});
});
});
}
initMap(): void {
let center = this.center;
let zooming = this.zoom;
this.map = new google.maps.Map(document.getElementById('viewDiv') as HTMLElement, {
center,
zoom: zooming
});
}
// To re-verify address in case it is typed in correct address format, but is not selected from autocomplete dropdown.
verifyAddress(): void {
let map = new google.maps.Map(this.searchElementRef.nativeElement);
let service = new google.maps.places.PlacesService(map);
let request = {
fields: ['name', 'geometry', 'formatted_address'],
query: this.searchString
};
service.findPlaceFromQuery(request, (place, status) => {
// console.log(status);
if (status === google.maps.places.PlacesServiceStatus.OK) {
if (place[0].formatted_address === request.query) {
this.isAddress = true;
this.zoom = 12;
if (place[0].geometry) {
if (!this.coloradoBounds.contains(place[0].geometry.location)) {
alert('The search location is outside of the bounds of Colorado.');
return;
}
// set latitude, longitude and zoom
this.lat = place[0].geometry.location.lat();
this.lng = place[0].geometry.location.lng();
this.center = { lat: this.lat, lng: this.lng };
this.bounds = place[0].geometry.viewport;
}
}
}
this.mapSearch();
});
}
Right now it looks like this:it can be typed in both address and keywords with autocomplete
Aucun commentaire:
Enregistrer un commentaire