I'm working on a search functionality where I use Google's autocomplete javascript library to get suggestions and pass it to AwesomeComplete library to populate it nicely in a search box. One of the requirement is strictly not to show any businesses in the search prediction. Is there a way to restrict businesses from the autocomplete suggestions?
I know that we can include different types to show up on the suggestion by adding them into the types attribute. And I have already tried with setting different types other than 'establishment', but still, I'm seeing a lot of businesses for even simple keywords.
var googleDisplaySuggestion = function(predictions, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
return;
}
var list = predictions.map(function (prediction) {
return {
label: prediction.description,
value: prediction.id,
}
});
awesome.list = list; // final list being sent to awesome complete
};
var googleList = new google.maps.places.AutocompleteService();
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(44.84808025602071,-78.321533203125),
new google.maps.LatLng(42.93631775765237,-80.584716796875),
);
var searchOptions = {
input: val, // Assume the value comes from input box
type: ['street_address','(cities)','library','airport'], // sample types other than businesses
componentRestrictions: {country: 'ca'},
bound: defaultBounds,
strictBounds: true,
location: new google.maps.LatLng(43.753994, -79.446807),
radius: 50000,
};
googleList.getPlacePredictions(searchOptions, googleDisplaySuggestion);
I expect to see suggestions without any businesses showing up
you have a mistake in your searchOptions object for the types properties.
Also, to return only geocoding results, rather than business results use types: ['geocode']
It should looks like:
var searchOptions = {
types: ['geocode']
};
However, only a single type is allowed.
https://developers.google.com/maps/documentation/javascript/reference/places-widget#AutocompleteOptions.types
I used google maps api for autocomplete of places.
Everythings works in localhost, but when i publish and upload it on server, it doesn't work...Why it happen? the dropdown of places does not show.
Here is my HTML:
<input type="text" id="autocomplete">
Here is my JS:
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
<script>
var autocomplete;
function initialize() {
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')), {
types: ['(cities)'],
componentRestrictions: { country: "ph" }
});
google.maps.event.addListener(autocomplete, 'place_changed', function () {
fillInAddress();
});
}
placeParser = function(place){
result = {};
for(var i = 0; i < place.address_components.length; i++){
ac = place.address_components[i];
result[ac.types[0]] = ac.long_name;
}
return result;
};
function fillInAddress() {
var place = autocomplete.getPlace();
document.getElementById("latitude").value = place.geometry.location.lat();
document.getElementById("longitude").value = place.geometry.location.lng();
components = placeParser(place);
}
initialize();
There are 3 issues
you are calling initialize without knowing if the maps-API already has been loaded, remove the call of initialize and use the callback-parameter of the maps-API instead
the maps-API now requires a key.
As it seems there are circumstances(undocumented) where it may work without a key(I guess for requests from localhost and from domains which have been used the maps-API before a key has been required), probably your domain doesn't match this criteria, so you should/must use a key
(Additionally)I would call it a bug by google:
As it seems, now the use of the Places-library requires that the Places API Web Service also has been activated for a project( before it was sufficient to activate only the Maps JavaScript API )
I need to create typeahead service for cities and so on.
At the same time I need to use a typeahead directive (ng2-bootstrap), so I just need an array of strings which I'll be given by my service.
I decided to use google maps for that.
This code was taken from an example of google maps api
function initAutocomplete() {
// Create the autocomplete object, restricting the search to geographical
// location types.
autocomplete = new google.maps.places.Autocomplete(
/** #type {!HTMLInputElement} */(document.getElementById('autocomplete')),
{types: ['geocode']});
// When the user selects an address from the dropdown, populate the address
// fields in the form.
autocomplete.addListener('place_changed', fillInAddress);
}
I need to use it with Angular2... how can I do that? And is it possible?
Thank you in advance and good luck!
I would set an object from the callback associated with your event. Here is a sample:
autocomplete.addListener('place_changed', () => {
this.selectedPlace = autocomplete.getPlace();
});
and bind the form against this object
<form>
Name: <input [(ngModel)]="selectedPlace.name"/>
(...)
</form>
Edit
You need to reference an element to apply on using the ViewChild decorator:
<div #autocomplete></div>
and in the component:
#ViewChild('autocomplete')
autocompleteElt:ElementRef;
ngAfterViewInit() {
this.initAutocomplete();
}
initAutocomplete() {
this.autocomplete = new google.maps.places.Autocomplete(
this.autocompleteElt.nativeElement,
{types: ['geocode']});
(...)
}
I'm looking to use Google Place Autocomplete on one of my Meteor App Input.
When I initialize a session, I have an InvalidValueError: not an instance of HTMLInputElement, but when I refresh the page one time, the autocomplete works well.
What do I need to change on my code in order to have autocomplete working on first session?
My code:
if (Meteor.isClient) {
window.onload = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types:['geocode']}
);
google.maps.event.addListener(autocomplete,'place_changed',function(){
var place = autocomplete.getPlace();
});
};
}
Thanks for your help.
Call below code on-focus of input element.
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types:['geocode']}
);
You should try using Template instance:
Template.autocomplete.onRendered(function() {
// Your autocomplete function
// var autocomplete = ...
});
My template name is "autocomplete" in this example.
I've been looking at the example on:
http://code.google.com/apis/maps/documentation/javascript/examples/places-autocomplete.html
and have decided to incorporate it into my site.
Is it possible to limit the addresses to UK addresses only?
Try this:
var input = document.getElementById('searchTextField');
var options = {
types: ['(cities)'],
componentRestrictions: {country: 'tr'}//Turkey only
};
var autocomplete = new google.maps.places.Autocomplete(input,options);
You can't strictly/hard limit the locations that it finds, although there is a feature request in the system to do so, but you can set a 'bias' on the results. It's passed in as an argument to the autocomplete method as a google maps bounds object. Autocomplete will then favor locations within those boundaries. Note, however, that since this isn't a hard boundary, if there are matches for the search outside the boundaries it will return those.
From my usage it seems a bit buggy and can use some improvement - especially considering that anything outside your boundary is not tagged by proximity at all, so something one block outside the boundary is just as likely to show as something 1000 miles outside, so make sure you play around with getting the boundaries working right.
You can intercept the JSONP results that are returned by the google.maps.places.Autocomplete functionality and use them as you see fit, such as to limit by country and display the results.
Basically you redefine the appendChild method on the head element, and then monitor the javascript elements that the Google autocomplete code inserts into the DOM for JSONP. As javascript elements are added, you override the JSONP callbacks that Google defines in order to get access to the raw autocomplete data.
It's a bit of a hack, here goes (I'm using jQuery but it's not necessary for this hack to work):
//The head element, where the Google Autocomplete code will insert a tag
//for a javascript file.
var head = $('head')[0];
//The name of the method the Autocomplete code uses to insert the tag.
var method = 'appendChild';
//The method we will be overriding.
var originalMethod = head[method];
head[method] = function () {
if (arguments[0] && arguments[0].src && arguments[0].src.match(/GetPredictions/)) { //Check that the element is a javascript tag being inserted by Google.
var callbackMatchObject = (/callback=([^&]+)&|$/).exec(arguments[0].src); //Regex to extract the name of the callback method that the JSONP will call.
var searchTermMatchObject = (/\?1s([^&]+)&/).exec(arguments[0].src); //Regex to extract the search term that was entered by the user.
var searchTerm = unescape(searchTermMatchObject[1]);
if (callbackMatchObject && searchTermMatchObject) {
var names = callbackMatchObject[1].split('.'); //The JSONP callback method is in the form "abc.def" and each time has a different random name.
var originalCallback = names[0] && names[1] && window[names[0]] && window[names[0]][names[1]]; //Store the original callback method.
if (originalCallback) {
var newCallback = function () { //Define your own JSONP callback
if (arguments[0] && arguments[0][3]) {
var data = arguments[0][4]; //Your autocomplete results
//SUCCESS! - Limit results here and do something with them, such as displaying them in an autocomplete dropdown.
}
}
//Add copy all the attributes of the old callback function to the new callback function. This prevents the autocomplete functionality from throwing an error.
for (name in originalCallback) {
newCallback[name] = originalCallback[name];
}
window[names[0]][names[1]] = newCallback; //Override the JSONP callback
}
}
//Insert the element into the dom, regardless of whether it was being inserted by Google.
return originalMethod.apply(this, arguments);
};
James Alday is correct:
http://code.google.com/apis/maps/documentation/javascript/places.html#places_autocomplete
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(49.00, -13.00),
new google.maps.LatLng(60.00, 3.00));
var acOptions = {
bounds: defaultBounds,
types: ['geocode']
};
it is somewhat annoying as searching for Durham gives Durham, North Carolina as the second result, regardless of how you try to persuade it to region bias - you can set it to viewport map bounds and it'll still try to suggest NC state... The jQuery solution can be found here, but doesn't seem to give as many results as the v3 API.
http://code.google.com/p/geo-autocomplete/
The best way you would go about doing this, is to query the places api yourself and appending the queried string with your country. Or, of course, use the geo-autocomplete jQuery plugin.
Just change the google domain for the maps to your country domain and it will automatically search within your country only:
So:
http://maps.google.com/maps/api/geocode/xml?address={0}&sensor=false&language=en
To:
http://maps.google.nl/maps/api/geocode/xml?address={0}&sensor=false&language=nl
Try something like this.
// Change Bangalore, India to your cities boundary.
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var autocomplete = new google.maps.places.Autocomplete(this, {
bounds: bangaloreBounds,
strictBounds: true,
});
autocomplete.addListener('place_changed', function () {
});
I find that if you set the map to roughly where you want then set bounds to it, the search finds places in that area first. You do not to physically show the map.
It works better than giving random overseas addresses first, setting to country does not work.
The code for autocomplete to get latln is:
<div id="map_canvas"></div>
<input type="text" name="location" id="location" placeholder="Type location...">
<input type="text" name="loc_latitude" id="latitude">
<input type="text" name="loc_longitude" id="longitude">
and the JS is:
$(document).ready(function () {
var mapOptions = {
center: new google.maps.LatLng(52.41041560, -1.5752999),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
var autocomplete;
autocomplete = new google.maps.places.Autocomplete((document.getElementById(searchInput)), {
types: ['geocode'],
});
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var near_place = autocomplete.getPlace();
document.getElementById('latitude').value = near_place.geometry.location.lat();
document.getElementById('longitude').value = near_place.geometry.location.lng();
});
});
$(document).on('change', '#'+searchInput, function () {
document.getElementById('latitude').value = '';
document.getElementById('longitude').value = '';
});
Not exactly what you asked for but it works for me.