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/
?
Related
Please provide me proper solution for following code
how can I pass the Google API Key
function load_map_from_address(mapid, address) {
// check if gps has been locally cached.
geocoder = new google.maps.Geocoder();
//alert(geocoder);
var geocoderAPIKey = 'geocoderAPIKey ';
geocoder.geocode({ 'address': address }, function (results, status) {
//alert(status);
if (status == "OK") {
var gps = results[0].geometry.location;
create_map(gps.lat(), gps.lng(), mapid);
}
else {
$('#' + mapid).html('<div class="map_canvas_text "><h4>address not found</h4></div>').show();
}
});
}
You can mention it when you include the Google map js . Something like .
Path-to-google-map js?key=yourApiKey
In you're script tag
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
}
});
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.');
}
});
}
I am trying to follow this Google Maps API geocode function problem code to use the Google Geocode API, but I'm doing something wrong. I am starting with the geocode and then the jQuery validator but somehow the status is not getting set. Any help?
jQuery(document).ready(function($) {
var shvalidator = $('#post').validate({
rules: {
post_title: { required:true }
},
messages: {
post_title: {required:jQuery.format("Enter the name of the venue")}
}
});
function getAddress() {
var geocoder = new google.maps.Geocoder();
var fulladdress = $('#sh_venue_address1').val()+' ' \
+$('#sh_venue_address2').val()+' ' \
+$('#sh_venue_city').val()+' ' \
+$('#sh_venue_state').val()+' ' \
+$('#sh_venue_postalcode').val();
alert(fulladdress );
var a,b;
geocoder.geocode( { 'address': fulladdress},
function(results, status) {
//**//
if (status == google.maps.GeocoderStatus.OK) {
a = results[0].geometry.location.lat();
b = results[0].geometry.location.lng();
setAddress(a,b);
}
});
}
// this is the callback method that waits for response from google
function setAddress(lat,lng) {
$('#sh_venue_latitude').val(lat);
$('#sh_venue_longitude').val(lng);
alert ($('#sh_venue_latitude').val());
}
// this is used to validate the form before submitting
$('#post').submit(function() {
getAddress();
if (shvalidator.valid()==true){
return true;
} else {
$('#ajax-loading').hide();
$('#publish').removeClass('button-primary-disabled');
return false;
}
});
});
I assume it is not working because the function getAddress is not executed completely before the processing of the submit (because its an asynchronous call for geocoding the address).
I would suppose to do sth like this in the submit function:
getAddress(function(){
if (shvalidator.valid()==true){
return true;
} else {
$('#ajax-loading').hide();
$('#publish').removeClass('button-primary-disabled');
return false;
}
});
and change the getAddress function to:
function getAddress(callback){
...
setAddress(a,b);
callback();
...
}
This is the code I am working from:
http://jsfiddle.net/njDvn/75/
var GeoCoded = {done: false};
$(document).ready(function(){
console.log('ready!');
autosuggest();
console.log($('#myform input[type="submit"]'));
$('#myform').on('submit',function(e){
if(GeoCoded.done)
return true;
e.preventDefault();
console.log('submit stopped');
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('location').value;
$('#myform input[type="submit"]').attr('disabled',true);
geocoder.geocode({
'address': address
},
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latLng = results[0].geometry.location;
$('#lat').val(results[0].geometry.location.lat());
$('#lng').val(results[0].geometry.location.lng());
//if you only want to submit in the event of successful geocoding, you can only trigger submission here.
GeoCoded.done = true;
$('#myform').submit();
} else {
console.log("Geocode was not successful for the following reason: " + status);
//enable the submit button
$('#myform input[type="submit"]').attr('disabled',false);
}
});
});
});
This works how I want BUT, I wanted to complete the geocode when someone clicks on the autocomplete. So, when they type something and click on a suggestion from the autosuggest list, it actually completes the geocode call when the click the result.
If anyone could tell me if this is possible I would really appreciate it, because I havent been able to figure out how to do it myself.
Autocomplete incorporates geocoding automatically. Example here.
Edit:
Here is the gist of that example:
The key lines for creating the autocomplete control are:
var input = document.getElementById('searchTextField');
var options = {
types: [],
componentRestrictions: {country: 'us'}
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
You also need to load the Places library:
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
and in your HTML:
<input id="searchTextField" type="text" size="50" value="">
By the way, you don't "add autocomplete to the geocoder".The Places Autocomplete class includes geocoding capabilities.