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 am sure i have structured this wrong, but the event listener for "dragend" is not firing. When I change the event to bounds_changed or center_changed then it only fires on the initial page load. Is there anything that stands out as to why it is behaving like this?
I basically just want to call my searchStores() function everytime the map is repositioned so it becomes reactive to the user.
var map;
$(document).ready(function () {
var latlng = new google.maps.LatLng(36.2994410, -82.3409052);
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// create the new map with options
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$("#btnSearch").click(function(){
//Convert Address Into LatLng and Retrieve Address Near by
convertAddressToLatLng($("#txtAddress").val());
});
//send user to print/save view on click
$("#saveAs").click(function() {
window.location.href = "https://54.90.210.118/test.html?address=" + $("#txtAddress").val() + '&radius=' + $("#radiusO").val();
});
//WHAT IS GOING ON WITH THIS GUY???
google.maps.event.addListener(map, "dragend", function() {
alert('map dragged');
});
});
$(document).one('ready', function(){
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
latlngloc = new google.maps.LatLng(pos.lat, pos.lng);
map.setCenter(pos);
$("#divStores").html('');
searchStores(latlngloc);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
});
Thanks for the help! I found the issue was on another function that ended up clearing the map object and then recreating it. Therefore removing the listener.
Sorry for the confusion, and thanks for pointing out that it worked on Jfiddle. I thought it was something to do with how I was calling it.
I am really new to Javascript and having to teach myself bit by bit. Thanks for all the help! =)
I'm trying to use Leaflet to get the map coordinates of somewhere a user has right clicked. I've been going through the Leaflet API and so far I've figured out that I need to listen to the contextmenu event and use mouseEventToLatLng method to get the coordinates when clicked. However, when I go through and debug my code I'm not seeing an accessible latLng variable anywhere. Did I miss understand something in the API?
function setMarkers() {
document.getElementById("transitmap").addEventListener("contextmenu", function( event ) {
// Prevent the browser's context menu from appearing
event.preventDefault();
var coords = L.mouseEventToLatLng( event );
});
};
What you want to get is mousemove event. This is basically how you do it,
var lat, lng;
map.addEventListener('mousemove', function(ev) {
lat = ev.latlng.lat;
lng = ev.latlng.lng;
});
document.getElementById("transitmap").addEventListener("contextmenu", function (event) {
// Prevent the browser's context menu from appearing
event.preventDefault();
// Add marker
// L.marker([lat, lng], ....).addTo(map);
alert(lat + ' - ' + lng);
return false; // To disable default popup.
});
The coordinates of the right click event should be directly available as latlng property of the event argument of the "contextmenu" listener.
map.on("contextmenu", function (event) {
console.log("Coordinates: " + event.latlng.toString());
L.marker(event.latlng).addTo(map);
});
Demo: http://plnkr.co/edit/9vm81YsQxnkAFs35N8Jo?p=preview
I am using google 'idle' event listener to upload markers on map (with angularjs). My code is
$scope.LoadSearchPropertyOnPortFolioSales = function (PropertyName) {
if(PropertyName == ''){
google.maps.event.addListener(map, 'idle', function () {
var PropertyList = PropertyService.GetSearchPropertyForPortfolio($scope.PortfolioId, $scope.PropertyName, this.center.lat(), this.center.lng(), 0.005, 0.005);
PropertyList.then(function (pl) {
DrawPropertyOnPortFolioSale(pl.data, $scope.PropertyName);
},
});
}
else
{
//Stop event listener
}
}
I want the event listener only work when PropertyName that is passed have no value. But when PropertyName have some value in it i want to stop event listener. How do i stop event listener......
There's also a function which removes all of the listeners at the same time:
clearListeners(instance:Object, eventName:string);
//In your case:
google.maps.event.clearListeners(map, 'idle');
Here's the Google Maps API reference where you can read about it.
With the Google Maps JS API v3, I want to drop a marker where the user clicks on the map, while keeping the default behavior when the user double clicks (and not adding any marker on the map).
I thought about defining a timeout on click event. If a double click event is triggered within the next few milliseconds, the timeout is cancelled. If not, the marker is placed on the map when the timeout expires.
But it doesn't really look like the best solution ever.
Is there a more elegant way to handle this?
Thanks.
I just found an hackish solution which works but introduce a small waiting time (200ms, this is the minimum to make it work, but I don't know if it is client dependent)
var update_timeout = null;
google.maps.event.addListener(map, 'click', function(event){
update_timeout = setTimeout(function(){
do_something_here();
}, 200);
});
google.maps.event.addListener(map, 'dblclick', function(event) {
clearTimeout(update_timeout);
});
Hope this helps!
The easiest way to solve it.
var location;
var map = ...
google.maps.event.addListener(map, 'click', function(event) {
mapZoom = map.getZoom();
startLocation = event.latLng;
setTimeout(placeMarker, 600);
});
function placeMarker() {
if(mapZoom == map.getZoom()){
new google.maps.Marker({position: location, map: map});
}
}
shogunpanda's solution is better (see below)
You can take advantage of, dblclick fires if it is a double click, and single click fires in such occations only once.
runIfNotDblClick = function(fun){
if(singleClick){
whateverurfunctionis();
}
};
clearSingleClick = function(fun){
singleClick = false;
};
singleClick = false;
google.maps.event.addListener(map, 'click', function(event) {// duh! :-( google map zoom on double click!
singleClick = true;
setTimeout("runIfNotDblClick()", 500);
});
google.maps.event.addListener(map, 'dblclick', function(event) {// duh! :-( google map zoom on double click!
clearSingleClick();
});
See http://www.ilikeplaces.com
If you're using underscore.js or* lodash here's a quick and elegant way to solve this problem
// callback is wrapped into a debounce function that is called after
// 400 ms are passed, it provides a cancel function that can be used
// to stop it before it's actually executed
var clickHandler = _.debounce(function(evt) {
// code called on single click only, delayed by 400ms
// adjust delay as needed.
console.debug('Map clicked with', evt);
}, 400);
// configure event listeners for map
google.maps.event.addListener(map, 'click', clickHandler);
google.maps.event.addListener(map, 'dblclick', clickHandler.cancel);
* Debounce.cancel is implemented only in lodash (with this commit), underscore.js does not implement it
A cleaner way to implement the setTimeout() approach is to trigger custom events for single clicks.
The following function takes any Google Maps interface object (e.g. map, marker, polygon etc.) and sets up two custom events:
singleclick: called 400ms after a click if no other clicks have occured
firstclick: called whenever a click event occurs, unless a click has already occured in the last 400ms (this is handy for showing some kind of immediate click feedback to the user)
function addSingleClickEvents(target) {
var delay = 400;
var clickTimer;
var lastClickTime = 0;
google.maps.event.addListener(target, 'click', handleClick);
google.maps.event.addListener(target, 'dblclick', handleDoubleClick);
function handleClick(e) {
var clickTime = +new Date();
var timeSinceLastClick = clickTime - lastClickTime;
if(timeSinceLastClick > delay) {
google.maps.event.trigger(target, 'firstclick', e);
clickTimer = setTimeout(function() {
google.maps.event.trigger(target, 'singleclick', e);
}, delay);
} else {
clearTimeout(clickTimer);
}
lastClickTime = clickTime;
}
function handleDoubleClick(e) {
clearTimeout(clickTimer);
lastClickTime = +new Date();
}
}
You can use it like so:
var map = ....
addSingleClickEvents(map);
google.maps.event.addListener(map, 'singleclick', function(event) {
console.log("Single click detected at: " + event.latLng);
}
I'm not sure, but if you add event handlers to both 'click' & 'dblclick' events, where you say to put marker on a click, and don't take any action on double click, then you can skip the adding of timeouts (the maps API can differ what is click and what is double click)
google.maps.event.addListener(map, 'click', function (event) {
placeMarker(event.latLng);
});
google.maps.event.addListener(map, 'dblclick', function(event) {
//DO NOTHING, BECAUSE IT IS DOUBLE CLICK
});
The placeMarker(latLng) is custom added function which adds marker on the given location:
var marker = new google.maps.Marker({
position: location,
draggable: true,
map: map
});
map.setCenter(location);