I can't get autocomplete input with jquery .val(), because .val() only returns input value which was typed by myself but not what was added by autocomplete.
jquery .val() only returns full value if make changes on other fields.
I use google maps autocomplete for address, and than I pass that address to google maps api to get distances between two addresses. Problem is that this "start = $('#id_rent_delivery_address').val()" only gets address part which is typed manually but not autocompleted.
Maybe you have any ideas how I could fix it?
My code:
<script>
$(document).ready(function() {
initAutocomplete();
});
var autocomplete, autocomplete2;
function initAutocomplete() {
// Create the autocomplete object, restricting the search to geographical
// location types.
autocomplete = new google.maps.places.Autocomplete(
/** #type {!HTMLInputElement} */(document.getElementById('id_rent_withdraw_address')),
{types: ['geocode']});
autocomplete2 = new google.maps.places.Autocomplete(
/** #type {!HTMLInputElement} */(document.getElementById('id_rent_delivery_address')),
{types: ['geocode']});
// When the user selects an address from the dropdown, populate the address
// fields in the form.
}
</script>
<script type="text/javascript">
$(document).on('change', '#rent-confirm-form', function() {
var start = $('#id_rent_delivery_address').val();
var end = $('#id_rent_withdraw_address').val();
GetRoute(start, end);
});
function GetRoute(start, end) {
//*********DISTANCE AND DURATION**********************//
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [start],
destinations: [end],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function (response, status) {
if (status == google.maps.DistanceMatrixStatus.OK && response.rows[0].elements[0].status != "ZERO_RESULTS") {
var distance = response.rows[0].elements[0].distance.text;
var duration = response.rows[0].elements[0].duration.text;
console.log(distance);
console.log(duration);
console.log(start);
console.log(end);
} else {
console.log("Unable to find the distance via road.");
}
});
}
</script>
Solved by myself. Just simulated form change with jquery trigger method.
$( "#anyInput" ).trigger("change");
Related
I'm bad with Javascript and would like your help!
Hi, I'm building a Rails application and would like to add some features related to geoloction. For that I get the current location of the user with JS and then print it with HTML.
As you guys will see, my code runs every time the page loads, but when my routes change, for example: /about, /settings, /events, it simply disappear and I have to load the page again to print the HTML element.
/* CURRENT LOCATION */
function geolocationSuccess(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var geocoder = new google.maps.Geocoder();
var latlng = {lat: latitude, lng: longitude};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results[0]){
var user_address = results[0].formatted_address;
document.getElementById("current_location").innerHTML = user_address;
}else {
console.log('No results found for these coords.');
}
}else {
console.log('Geocoder failed due to: ' + status);
}
});
}
function geolocationError() {
console.log("please enable location for this feature to work!");
}
$(document).ready(function() {
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
} else {
alert("Geolocation not supported!");
}
});
How can I have the current location printed on this element in all my application routes?
I wouldn't like to request this information every time.
Maybe a cookie? I don't know...
or request just once every some time
What do you guys recommend? Please help me :)
You can use localStorage for this purpose: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
localStorage allows you to save data between browser sessions and windows.
An example usage might be:
...
// Somewhere in geocode request callback
localStorage.setItem('user_address', results[0].formatted_address)
...
// Somewhere in your render code
document.getElementById("current_location").innerHTML =
localStorage.getItem('user_address')
...
I have a problem where I have some code which I want to apply to two slightly different applications, but 75% of the code will be the same. This is where I am with things:
http://jsfiddle.net/spadez/H6SZ2/6/
$(function () {
var input = $("#loc"),
lat = $("#lat"),
lng = $("#lng"),
lastQuery = null,
lastResult = null, // new!
autocomplete;
function processLocation(callback) { // accept a callback argument
var query = $.trim(input.val()),
geocoder;
// if query is empty or the same as last time...
if( !query || query == lastQuery ) {
callback(lastResult); // send the same result as before
return; // and stop here
}
lastQuery = query; // store for next time
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());
lastResult = true; // success!
} else {
alert("Sorry - We couldn't find this location. Please try an alternative");
lastResult = false; // failure!
}
callback(lastResult); // send the result back
});
}
var ctryiso = $("#ctry").val();
var options = {
types: ["geocode"]
};
if(ctryiso != ''){
options.componentRestrictions= { 'country': ctryiso };
}
autocomplete = new google.maps.places.Autocomplete(input[0], options);
google.maps.event.addListener(autocomplete, 'place_changed', processLocation);
$('#search_form').on('submit', function (event) {
var form = this;
event.preventDefault(); // stop the submission
processLocation(function (success) {
if( success ) { // if the geocoding succeeded, submit the form
form.submit()
}
});
});
});
When the submit form button is pressed it will do the following (this works already):
Check if result is already geocoded from autosuggest click
If not, geocode
Submit the form if successful
When the Geocode button is pressed I want it to do the following (this doesn't work):
Check if result is already geocoded from autosuggest click
If not, geocode
So my question is, how can I make it so I can use the same code for both scripts without having to duplicate it twice. My idea was to do the following:
Have a function for the "submit form" button which includes submitting the form
Have a function for the geocode button which does not include submitting the form
I would rather use a function for each button rather than using some kind of flag, but I am completely stuck on how to implement this, every time I work on it I end up breaking the script completely. I am new to JavaScript.
If the only difference is that one submits and the other does not, allow a callback to be passed into the function, and the one that submits can pass a submit to the function.
I am new to javascript but I am having a hard time creating code which can achieve this logic:
I am trying to achieve the following logic:
If a user enters text in location box and DOES click autosuggestion Then geocode and set coded flag to "True"
If a user enters text in location DOES NOT click autosuggestion Keep coded flag to "False"
If a user changes the text in location box Make sure "coded" flag is set to "false" - Since the text doesnt match the coordinates we
fetched for it now
If a user clicks search button Check "coded" flag If true, submit form If false, process geocode, and if successful, submit form
This is how far I got before I got stuck: LINK
Even when I click on an autosuggested link, which initiates a geocode, and then do not change the content in the input box, when I hit search it says "Location not geocoded - Process location first". I feel like my logic in the programming is wrong but I am not sure how to fix it without lots of ugly repetitive code.
FULL CODE
geocode();
// SET COOKIE FOR TESTING PURPOSES
$.cookie("country", "uk");
// GEOCODE FUNCTION
function geocode() {
var coded = false;
console.log(coded);
var input = document.getElementById('loc');
var options = {
types: ['geocode']
};
var country_code = $.cookie('country');
console.log(country_code);
if (country_code) {
options.componentRestrictions = {
'country': country_code
};
}
var autocomplete = new google.maps.places.Autocomplete(input, options);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
processLocation();
});
// ON SUBMIT - WORK OUT IF WE ALREADY HAVE THE RESULTS FROM AUTOCOMPLETE FUNCTION
$('#searchform').on('submit', function(e) {
console.log(coded);
e.preventDefault();
if(coded == true) {
console.log("Location already geocoded - Submitting form");
$('#searchform').submit();
}
else {
console.log("Location not geocoded - Process location first");
processLocation();
}
});
// CHECK TO SEE IF INPUT HAS CHANGED SINCE BEING GEOCODED
// IF "CODED" VAR IS FALSE THEN WE WILL GEOCODE WHEN SEARCH BUTTON HIT
$("#loc").bind("change paste keyup", function() {
var coded = false;
console.log("Content changed - Coordinates no longer valid");
});
};
// GEOCODE THE LOCATION
function processLocation(){
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('loc').value;
geocoder.geocode({
'address': address
},
// RESULTS - STORE COORDINATES IN FIELDS OR ERROR IF NOT SUCCESSFUL
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var coded = true;
console.log("Geocode Successful");
$('#lat').val(results[0].geometry.location.lat());
$('#lng').val(results[0].geometry.location.lng());
} else {
var coded = false;
console.log("Geocode unsuccessful");
alert("Sorry - We couldn't find this location. Please try an alternative")
}
});
}
You are using too many local variables coded. YOu should define one global flag and then can use set it.
When you so
function geocode() {
....
var coded = false;
.....
}
function processLocation(){
....
var coded = true;
....
}
These are not the same coded. To access it globally. You could do somethink like
var coded = false; //initialize with a proper default value function geocode() {
function geocode() {
....
coded = false;
.....
}
function processLocation(){
....
coded = true;
....
}
Note that I'm putting coded outside of all the functions and access it without the var. You should read up on this topic .
I am trying to use the autocomplete jquery API. The issue is I want to trigger a function or a set of code once I selected an item but i keep getting undefined items.
Here my code:
function init()
{
var input = document.getElementById('event_address');
var options =
{
types: ['geocode']
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
// event triggered when drop-down option selected
select: function(event, ui) {
var address = document.getElementById(event_address).value;
geocoder.geocode( { 'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
alert(results[0].geometry.locations);
}
});
}
}
Here my errors:
Uncaught SyntaxError: Unexpected token (
Thanks
First, I believe what you are referring to is jqueryUI's autocomplete widget. The select method fires when an autocomplete selection has been made. I'm assuming what you're trying to do would be to display the coordinates of a geographical region chosen from the auto complete list.
you would need to do something like this:
$('#inputbox').autocomplete({
select: function(event, ui){
// code to get selection
var address = $('#inputbox').text();
//assuming your geocode is correct
geocoder.geocode( { 'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
alert(results[0].geometry.locations);
}
});
}
});
For more info, see the autocomplete documentation: http://api.jqueryui.com/autocomplete/#event-select
I want to trigger a function when the submit button is pressed on the form and wait for the javascript function to complete, then continue the form submission. I dont want the form to submit before the javascript function has completed.**
This is what I have at the moment:
http://jsfiddle.net/njDvn/68/
function autosuggest() {
var input = document.getElementById('location');
var options = {
types: [],
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
<!-- Get lat / long -->
function getLatLng() {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('location').value;
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());
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
<!-- Load it -->
window.onload = autosuggest;
You can intercept the form submission, abort it and send the geocoding request to Google.
When the server responds, you can re-submit the form from the callback (or display an error in case of failure).
Store the state of the request somewhere (for the sake of simplicity, I'm using a global variable in my example). In this case, it's just a flag that indicates whether or not the geocoding request was completed successfully (so that now, when the form is submitted and the listener is re-triggered, it will know not to re-send the geocoding request).
http://jsfiddle.net/njDvn/75/
Feel free to remove the console logging.
You may also want to make the lat/long fields hidden.
var GeoCoded = {done: false}; // this holds the status of the geo-coding request
$(document).ready(function(){
autosuggest(); // place your auto-suggest (now called autocomplete) box
$('#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;
// disable the submit button
$('#myform input[type="submit"]').attr('disabled',true);
// send the request
geocoder.geocode({
'address': address
},
function (results, status) {
// update the status on success
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; // this will prevent an infinite loop
$('#myform').submit();
} else { // failure
console.log("Geocode was not successful for the following reason: " + status);
//enable the submit button
$('#myform input[type="submit"]').attr('disabled',false);
}
});
});
});
First you need to prevent the form to be submitted, add a return false at the end of getLatLng() function.
Then when the geocoding is done, submit the form manually with document.getElementsByTagName('form')[0].submit()
Here's an updated jsfiddle: http://jsfiddle.net/njDvn/70/
myFunction = new function(callback) {
$.ajax({...}).done(callback());
}
myFunction(new function() {
getLatLng();
});
Here you need to call myFunction onSubmit event.
As MasterAM has stated, all you need do is the following:
/// I've included the following function to allow you to bind events in a
/// better way than using the .onevent = function(){} method.
var addEvent = (function(){
if ( window.addEventListener ) {
return function(elm, eventName, listener, useCapture){
return elm.addEventListener(eventName,listener,useCapture||false);
};
}
else if ( window.attachEvent ) {
return function(elm, eventName, listener){
return elm.attachEvent('on'+eventName,listener);
};
}
})();
/// add another window.onload listener
addEvent(window,'load',function(){
/// find the form, obviously should use whatever id you have on your form
var form = document.getElementById('my_form');
form.preventSubmit = true;
/// add our onsubmit handler
addEvent(form,'submit',function(e){
/// only stop the form if we haven't already
if ( form.preventSubmit ) {
/// place/call whatever code you need to fire before submit here.
alert('submit was blocked!');
/// after that code is complete you can use the following
form.preventSubmit = false;
form.submit();
/// return false prevents the submit from happening
return false;
}
});
});