This question already has answers here:
Address validation using Google Maps API
(10 answers)
Closed 7 years ago.
I have wrote following example:
http://jsfiddle.net/214190tj/1/
html:
<label for="searchTextField">Please Insert an address:</label>
<br>
<input id="searchTextField" type="text" size="50">
<input type="submit" value="is valid">
js:
var input = document.getElementById('searchTextField');
var options = {componentRestrictions: {country: 'us'}};
new google.maps.places.Autocomplete(input, options);
Now it is working good but I need to check that uset didn't type something like "dsgfdsgfjhfg" when button clicks.
Please help to improve my code.
P.S.
this approximately make what I want but it executes in callback. I need a function which returns true or false.
function codeEditAddress(id) {
var address = document.getElementById('address' + id).value;
isValid = undefined;
geocoder.geocode({ 'address': address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
$("#mapLat" + id).val(results[0].geometry.location.lat());
$("#mapLng" + id).val(results[0].geometry.location.lng());
if (marker) {
marker.setMap(null);
}
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
marker.setMap(map);
isValid = true;
} else {
isValid = false;
}
});
}
You're going to have to re-design your address checker function so that you pass in a callback function. Returning a value from an asynchronous operation inherently does not make sense. You'll want something like this:
function codeEditAddress(id, callback) {
var address = document.getElementById('address' + id).value;
geocoder.geocode({ 'address': address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
$("#mapLat" + id).val(results[0].geometry.location.lat());
$("#mapLng" + id).val(results[0].geometry.location.lng());
if (marker) {
marker.setMap(null);
}
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
marker.setMap(map);
callback(true);
} else {
callback(false);
}
});
}
To call this function:
codeEditAddress(id, function(isValid) {
if (isValid) {
// submit form, do whatever
}
else {
// show error message, etc
}
});
Related
This question already has answers here:
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 8 years ago.
I am working on a hybrid app using the Appgyver Steroids framework and I'm trying to implement a 'detect user location' feature whereby the user can toggle a switch to choose whether they'd like their location (long & lat) to be detected automatically, or alternatively they can enter their location (city, postcode or county) into a text box and the longitude and latitude will be calculated on click of a button based on their input/selection.
When the user toggles the switch into the 'on' position and taps submit, the navigator.geolocation.getCurrentPosition is fired and calls the relevant functions which then stores their current longitude and latitude in localStorage. This works perfectly.
However, when the user toggles the switch into the 'off' position, my geocode function [manuallyGeoCode()] which codes their location into long and lat doesn't seem to fire in time and so the alert is fired straight after calling that geocode function before it has had time to actually set the localStorage value. I've researched using a callback and I've looked into using the jQuery deferred method, both of which I've had no success with using. Any help would be massively appreciated! Thanks for reading.
Here's my code:
<h3>Your location</h3>
<ul class="list">
<li class="item item-toggle">Use my current location
<label class="toggle toggle-balanced">
<input type="checkbox" id="myLocationToggle" checked="true">
<div class="track">
<div class="handle"></div>
</div>
</label>
</li>
<li class="item item-input">
<input type="text" id="userLocation" placeholder="City, town or postcode" disabled="true">
</li>
</ul>
<button class="button button-balanced" id="getLongLat">Get long/lat</button>
$(function(){
AutoGeoCode();
});
function AutoGeoCode(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
}
$('#getLongLat').on('click',function(){
localStorage.latToPost = '';
localStorage.lngToPost = '';
if(localStorage.userLatAutoDetected != '0' || localStorage.userLngAutoDetected != '0'){
localStorage.latToPost = localStorage.userLatAutoDetected;
localStorage.lngToPost = localStorage.userLngAutoDetected;
}
else{
manuallyGeoCode(); // this doesn't finish in time so it jumps to the alert below and shows empty values.
}
alert('geodata is: {'+localStorage.latToPost+'}, {'+localStorage.lngToPost+'}');
});
$('#myLocationToggle').on('click',function(){
if($(this).is(':checked')){
$('#userLocation').val('').prop('disabled',true);
AutoGeoCode();
}
else{
$('#userLocation').val('').prop('disabled',false);
localStorage.userLatAutoDetected = '0';
localStorage.userLngAutoDetected = '0';
}
});
function onSuccess(position){
localStorage.userLatAutoDetected = position.coords.latitude;
localStorage.userLngAutoDetected = position.coords.longitude;
}
function onError(error){
alert('current location could not be auto detected. Error: ' + error);
}
//Autocomplete location search box
function initialize() {
var address = (document.getElementById('userLocation'));
var autocomplete = new google.maps.places.Autocomplete(address);
autocomplete.setTypes(['geocode']);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
}); //end google.maps.event
}
function manuallyGeoCode(){
var address = $('#userLocation').val();
geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
localStorage.latToPost = results[0].geometry.location.lat();
localStorage.lngToPost = results[0].geometry.location.lng();
}
else {
alert('Your location could not be geocoded.');
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Please find the difference in the handle and the manual geocode functions
$('#getLongLat').on('click',function(){
localStorage.latToPost = '';
localStorage.lngToPost = '';
if(localStorage.userLatAutoDetected != '0' || localStorage.userLngAutoDetected != '0'){
localStorage.latToPost = localStorage.userLatAutoDetected;
localStorage.lngToPost = localStorage.userLngAutoDetected;
alert('geodata is: {'+localStorage.latToPost+'}, {'+localStorage.lngToPost+'}');
}else{
manuallyGeoCode(function(){
alert('geodata is: {'+localStorage.latToPost+'},{'+localStorage.lngToPost+'}');
}); // this doesn't finish in time so it jumps to the alert below and shows empty values.
}
});
function manuallyGeoCode(cb){
var address = $('#userLocation').val();
geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
localStorage.latToPost = results[0].geometry.location.lat();
localStorage.lngToPost = results[0].geometry.location.lng();
cb();
}
else {
alert('Your location could not be geocoded.');
}
});
}
How do I get the longitude and latitude from the searched location with the google maps place search box api.
Im using the same code as the google demo - https://developers.google.com/maps/documentation/javascript/examples/places-searchbox
function GetLatlong() {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('textboxid').value;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
}
});
}
You can use the above function which will give you the latitude and longitude for the area entered by user.
The code on the link you provide shows a function to do when a search is entered. First, it creates an empty array of markers (the pins you see on the map once you perform a search).
So, check the function starting with:
google.maps.event.addListener(searchBox, 'places_changed', function() {
You'll see later on that a marker has been created (there's even a comment):
// Create a marker for each place.
var marker = new google.maps.Marker({
map: map,
icon: image,
title: place.name,
position: place.geometry.location
});
So, on place.geometry.location you have a Google Maps Location object. You could use place.geometry.location.lat() and place.geometry.location.lng().
Check here, too: https://stackoverflow.com/a/15315483/1012139
From the docs:
// Autocomplete Options
var defaultBounds = new google.maps.LatLngBounds();
var options = {
types: ['(cities)'],
bounds: defaultBounds
};
// get DOM's input element
var input = document.getElementById('location_address');
// Make Autocomplete instance
var autocomplete = new google.maps.places.Autocomplete(input, options);
// Listener for whenever input value changes
autocomplete.addListener('place_changed', function() {
// Get place info
var place = autocomplete.getPlace();
// Do whatever with the value!
console.log(place.geometry.location.lat());
});
HTML:
<input type="text" id="address" name="address" value=""> //Autocomplete input address
<input type="hidden" name="s_latitude" id="s_latitude" value="" /> //get latitude
<input type="hidden" name="s_longitude" id="s_longitude" value="" /> //get longitude
Javascript:
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places&callback=initMap"
async defer></script>
<script>
var input = document.getElementById('address');
var originLatitude = document.getElementById('s_latitude');
var originLongitude = document.getElementById('s_longitude');
var originAutocomplete = new google.maps.places.Autocomplete(input);
originAutocomplete.addListener('place_changed', function(event) {
var place = originAutocomplete.getPlace();
if (place.hasOwnProperty('place_id')) {
if (!place.geometry) {
// window.alert("Autocomplete's returned place contains no geometry");
return;
}
originLatitude.value = place.geometry.location.lat();
originLongitude.value = place.geometry.location.lng();
} else {
service.textSearch({
query: place.name
}, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
originLatitude.value = results[0].geometry.location.lat();
originLongitude.value = results[0].geometry.location.lng();
}
});
}
});
</script>
navigator.geolocation.getCurrentPosition(success => {
console.log(success) // `have the lat and long`
}, failure =>{
//`enter code here if failed`
});
I have some code which, when the search box is clicked, geocodes a location (unless laready done by the autosuggest) in the location box and should the submit the form.
The problem is, the form does not get submitted after the searhc button is clicked and the geocode is successful. Can anyone tell me where I am going wrong?
This is a link to the jsfiddle: http://jsfiddle.net/sR4GR/35/
This is the full code:
$(function () {
var input = $("#loc"),
lat = $("#lat"),
lng = $("#lng"),
lastQuery = null,
autocomplete;
function processLocation(query) {
var query = $.trim(input.val()),
geocoder;
if (!query || query == lastQuery) {
console.log("Empty or same variable");
return;
}
lastQuery = query;
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: query
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
lat.val(results[0].geometry.location.lat());
lng.val(results[0].geometry.location.lng());
} else {
alert("We couldn't find this location. Please try an alternative");
}
});
}
autocomplete = new google.maps.places.Autocomplete(input[0], {
types: ["geocode"],
componentRestrictions: {
country: "uk"
}
});
google.maps.event.addListener(autocomplete, 'place_changed', processLocation);
$('#searchform').on('submit', function (event) {
processLocation();
event.preventDefault();
});
});
I don't know what processLocation(query) expects for query, but idea would be this:
1. change function signature
function processLocation(query, doSubmit) { // <--- new parameter
var query = $.trim(input.val()),
geocoder;
if (!query || query == lastQuery) {
console.log("Empty or same variable");
return;
}
lastQuery = query;
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: query
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
lat.val(results[0].geometry.location.lat());
lng.val(results[0].geometry.location.lng());
if (doSubmit){
$('#searchform').submit(); //<-- new param usage
}
} else {
alert("We couldn't find this location. Please try an alternative");
}
});
}
2. remove this call
$('#searchform').on('submit', function (event) {
alert('Submitted')
event.preventDefault();
});
3. add this call
$('#search').click(function(){
processLocation(new Date(), true); //<-- don't know what's the first param
});
Tried to play around in your jsfiddle but had no success as I was constantly getting Empty or same variable message into console. I think you know your logic better and you'll figure out
I would just have the submit button disabled until the values are valid?
<input type="submit" value="Search" id="search" disabled="disabled">
search.removeAttr('disabled')
http://jsfiddle.net/sR4GR/38/
?
I have a form on my Jquery Mobile page where the user can insert a start-location and a destination.
These values will be saved inside the localstorage.
Now I'm trying to manipulate the input like this:
when you type (for instance) 'current' in the input-box, the user's location will be placed inside the localstorage-database instead of the word 'current'.
I already made this script to get the user's location:
var geocoder;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
//Get the latitude and the longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
codeLatLng(lat, lng)
}
function errorFunction(){
alert("Geocoder failed");
}
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results)
if (results[1]) {
//formatted address
document.getElementById('formatedAddress').innerHTML = results[0].formatted_address;
//find country name
for (var i=0; i<results[0].address_components.length; i++) {
for (var b=0;b<results[0].address_components[i].types.length;b++) {
//there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
city= results[0].address_components[i];
break;
}
}
}
}
}
}
);
}
The 2 input fields:
<label for="start">Startlocation:</label>
<input type="text" name="start" value="" id="start"/>
<label for="destination">Destination:</label>
<input type="text" name="destination" value="" id="destination"/>
I'm very new to javascript and jQuery and I can't seem to find a solution to my problem.
I hope someone could help me. Thanks!
var start = document.getElementById('start').value;
if (start == 'current') {
//set lat & long to current
}
else {
//read lat & long from input fields
}
This bit of logic may prove to be what you're after - however I do tend to agree with logical Chimp that UX is very important, and a "use current location" button may prove to be more useful to the user.
The address I have is a concatenated results[1].formatted_address retrieved from a database containing 6 numbers e.g 530456. I then geocoded it and placed a marker on a google map. This part is successful.
I now want to display the full address, results[0].formatted_address in a infowindow of the marker, so what I did was to reverse geocode the latLng of the marker to obtain the full address but caused the entire map to disappear. The way I did it is as such:
var address;
var eventwindow;
function codeAddress(postal) {
geocoder.geocode( {'address': postal + ", Singapore"}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
eventwindow = new google.maps.InfoWindow();
var markerE = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
});
address = getMarkerAddress(results[0].geometry.location);
google.maps.event.addListener(marker, 'click', function(){
if(eventwindow)
eventwindow.close();
eventwindow = new google.maps.InfoWindow({
content: address,
});
eventwindow.open(map,marker);
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function getMarkerAddress(location) {
geocoder.geocode({'latLng': location}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if(results[0])
{
address = results[1].formatted_address.substring(10);
}
}
else {
alert("Geocoder failed due to: " + status);
}
});
I don't know if I'm doing this right and and not sure where I went wrong. Is there another way to this problem? If so how?
I don't know if I'm doing this right and and not sure where I went wrong. Is there another way to this problem? If so how?
If you know the "correct" address, use that. You haven't provided enough details of your application to make suggestions on how to do that. You can avoid the uncertainty of the geocoder by storing the coordinates that are returned from the geocoder in your database along with the address, then if you find an error, you can fix it.
This article on geocoding strategies might help.