Getting a marker to update with API call data - javascript

I have an input box where user enters a city name and the updateMap function executes. It geolocates and maps the city with a marker. This then calls another function called updateTemp to update the marker title with the current temperature. I use ajax to get the temperature. I am very new to Javascript and was hoping to get a reason why the below code doesn't work (for educational purposes) and some solution.
<input id="cityInput" class="controls" type="text" placeholder="Search Box">
<input name="buttonExecute" onclick="updateMap(document.getElementById('cityInput'))" type="button" value="Execute" />
<div id="map"></div>
<script>
function updateMap(obj) {
var geo = new google.maps.Geocoder();
geo.geocode({'address':obj.value},function(results,status){
if(status == google.maps.GeocoderStatus.OK){
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(lat,lng);
var mapOptions = { center: latlng, zoom: 6,vmapTypeId: google.maps.MapTypeId.ROADMAP};
var mapElement = document.getElementById('map');
var map = new google.maps.Map(mapElement,mapOptions);
var latlngString = lat.toString() +','+lng.toString();
var URL = "https://api.forecast.io/forecast/APIKEY/"+latlngString;
var marker = new google.maps.Marker({position:latlng, map:map});
updateTemp(URL,marker)
}
});
}
function updateTemp(URL,marker){
$.ajax({
url: URL,
jsonp: "callback",
dataType: "jsonp",
success: function( response) {
var t = response['currently']['temperature'];
var msg = 'CURRENT TEMPERATURE: ' + t + 'F';
marker.setTitle(msg);
},
async:false
});
}
</script>

this works for me when I put my key in. Note the ajax change.
function updateMap(obj) {
var geo = new google.maps.Geocoder();
geo.geocode({'address':obj.value},function(results,status){
if(status == google.maps.GeocoderStatus.OK){
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(lat,lng);
var mapOptions = { center: latlng, zoom: 6,vmapTypeId: google.maps.MapTypeId.ROADMAP};
var mapElement = document.getElementById('map');
var map = new google.maps.Map(mapElement,mapOptions);
var latlngString = lat.toString() +','+lng.toString();
var URL = "https://api.forecast.io/forecast/68a746738dddfee5ac67c77bcb97e59b/"+latlngString;
marker = new google.maps.Marker({position:latlng, map:map});
updateTemp(URL,marker)
}
});
}
function updateTemp(URL,marker){
$.ajax({
url: URL,
type: "GET",
dataType: "jsonp",
success: function(response) {
var t = response['currently']['temperature'];
var msg = 'CURRENT TEMPERATURE: ' + t + 'F';
marker.setTitle(msg);
}
});
}

Your marker variable is local to the geocoder callback function. Make it global (or local to the updateMap function).
proof of concept fiddle
(simulates the ajax call with a call to setTimeout, give it 10 seconds to update the title of the marker)
code snippet:
var marker;
function updateMap(obj) {
var geo = new google.maps.Geocoder();
geo.geocode({
'address': obj.value
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(lat, lng);
var mapOptions = {
center: latlng,
zoom: 6,
vmapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapElement = document.getElementById('map');
var map = new google.maps.Map(mapElement, mapOptions);
var latlngString = lat.toString() + ',' + lng.toString();
var URL = "https://api.forecast.io/forecast/APIKEY/" + latlngString;
marker = new google.maps.Marker({
position: latlng,
map: map
});
updateTemp(URL, marker)
}
});
}
function updateTemp(URL, marker) {
/* $.ajax({
url: URL,
jsonp: "callback",
dataType: "jsonp",
success: function(response) {
var t = response['currently']['temperature'];
var msg = 'CURRENT TEMPERATURE: ' + t + 'F';
marker.setTitle(msg);
},
async: false
}); */
setTimeout(function() {
marker.setTitle("90 degrees");
}, 10000);
}
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input id="cityInput" class="controls" type="text" placeholder="Search Box">
<input name="buttonExecute" onclick="updateMap(document.getElementById('cityInput'))" type="button" value="Execute" />
<div id="map"></div>

Related

How to remove Google Map Markers without blinking?

I am trying to populate multiple markers via ajax request on 5 sec interval. Every thing is working fine, but markers blinks on each interval call.
I am clearing all markers & regenerating again on each interval call. I just want to re-generate markers without blinking.
Also, it's possible that ajax request can return different result set on each interval call.
Following is the code:
var map;
var places;
var markers = [];
var iw_map;
var markers_map = new Array();
function initialize() {
geocoder = new google.maps.Geocoder();
var latlngCenter = new google.maps.LatLng(25.1999721, 66.8354386);
iw_map = new google.maps.InfoWindow();
var mapOptions = {
center: latlngCenter,
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
fetchPlaces();
fitMapToBounds_map();
}
function fetchPlaces(cityId = null, hubId = null, riderId = null) {
clearMarkers();
$.ajax({
url: '{{ route('get-markers') }}',
method:'POST',
data: {'city_id': cityId, hub_id: hubId, rider_id: riderId},
dataType: 'json',
cache: false,
success: function(data) {
// console.log(markers);
var markerz = data.markers;
// clearMarkers();
$.each(markerz, function (i, dt) {
var marker_icon = {url: dt.icon};
var position = new google.maps.LatLng(dt.lat,dt.lng);
var marker = new google.maps.Marker({
map: map,
position: position,
icon: marker_icon
});
// newcoordinate = new google.maps.LatLng(dt.lat,dt.lng);
google.maps.event.addListener(marker, "click", function(event) {
$.ajax({
url: '{{ route('get-marker-info') }}',
method:'POST',
data: JSON.parse(dt.params),
success: function(data) {
iw_map.setContent(data.infoBox);
iw_map.open(map, marker);
}
});
});
markers.push(marker.getPosition());
markers_map.push(marker);
});
// fitMapToBounds_map();
}
});
}
function fitMapToBounds_map() {
var bounds = new google.maps.LatLngBounds();
if (markers.length>0) {
for (var i=0; i<markers.length; i++) {
console.log(markers[i]);
bounds.extend(markers[i]);
}
map.fitBounds(bounds);
}
}
function clearMarkers() {
for (var i = 0; i < markers_map.length; i++) {
markers_map[i].setMap(null);
}
markers_map = [];
}
function loadScript_map() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=false&v=3&libraries=places&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript_map;
setInterval(fetchPlaces, 5000);
This is untested code so it might need a few adjustments.
I renamed your variables with meaningful names and changed the logic to first add the new markers, then remove the old markers.
When you get your markers with AJAX, first empty the new_markers array, then plot the markers on the map, and add them to the new_markers array. Then clear the old markers from the map (markers array). The first time, this array will be empty so nothing will happen. Copy new_markers array to markers array. Repeat.
Here is the code:
var map;
var places;
var markers_positions = [];
var markers = [];
var new_markers = [];
var iw_map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlngCenter = new google.maps.LatLng(25.1999721, 66.8354386);
iw_map = new google.maps.InfoWindow();
var mapOptions = {
center: latlngCenter,
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
fetchPlaces();
fitMapToBounds_map();
}
function fetchPlaces(cityId = null, hubId = null, riderId = null) {
new_markers = [];
$.ajax({
url: '{{ route('get-markers') }}',
method: 'POST',
data: {
city_id: cityId,
hub_id: hubId,
rider_id: riderId
},
dataType: 'json',
cache: false,
success: function(data) {
$.each(data.markers, function(i, dt) {
var marker_icon = {
url: dt.icon
};
var position = new google.maps.LatLng(dt.lat, dt.lng);
var marker = new google.maps.Marker({
map: map,
position: position,
icon: marker_icon
});
google.maps.event.addListener(marker, "click", function(event) {
$.ajax({
url: '{{ route('get-marker-info') }}',
method: 'POST',
data: JSON.parse(dt.params),
success: function(data) {
iw_map.setContent(data.infoBox);
iw_map.open(map, marker);
}
});
});
markers_positions.push(marker.getPosition());
new_markers.push(marker);
clearMarkers();
});
}
});
}
function fitMapToBounds_map() {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers_positions.length; i++) {
console.log(markers_positions[i]);
bounds.extend(markers_positions[i]);
}
map.fitBounds(bounds);
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = new_markers;
}
function loadScript_map() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=false&v=3&libraries=places&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript_map;
setInterval(fetchPlaces, 5000);

Sending AJAX response to Google Maps location markers with JSON

Upon clicking a button, an AJAX response is called to output JSON based on a search query. I would like to use the variable all_locations from the AJAX response, to output into the Google map markers. Not too sure how this can be done. I researched into using async as false but to no success.
Form
<form id="filter">
<span class="ek-search-address col-xs-8">
<label for="address">Location</label>
<input id="address" name="property_location" value="New York" placeholder="Input Address" type="text"/>
</span>
<span class="ek-search-radius live-search col-xs">
<select id="radius_km">
<option value=1>1km</option>
<option value=2>2km</option>
<option value=5>5km</option>
<option value=30>30km</option>
</select>
</span>
<button onClick="showCloseLocations()">Search</button>
<input type="hidden" name="action" value="ek_search">
</form>
<div id="map_canvas">
AJAX call
jQuery(function($){
$('#filter').submit(function(){
var filter = $('#filter');
var ajaxurl = '<?php echo admin_url("admin-ajax.php", null); ?>';
data = { action: "ek_search"};
var all_locations = $.ajax({
url: ajaxurl,
data:data,
async:false,
type: 'POST', // POST
dataType: 'json',
success: function(response) {
console.log(response);
}
});
return false;
});
});
map.js
jQuery(function($) {
var map = null;
var radius_circle;
var markers_on_map = [];
var geocoder;
var infowindow;
new google.maps.places.Autocomplete(
(document.getElementById('address')), {
types: ['geocode']
});
//initialize map on document ready
$(document).ready(function() {
var latlng = new google.maps.LatLng(50.927978, -5.408908);
var myOptions = {
zoom: 17,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
geocoder = new google.maps.Geocoder();
google.maps.event.addListener(map, 'click', function() {
if (infowindow) {
infowindow.setMap(null);
infowindow = null;
}
});
});
function showCloseLocations() {
var i;
var radius_km = $('#radius_km').val();
var address = $('#address').val();
//remove all radii and markers from map before displaying new ones
if (radius_circle) {
radius_circle.setMap(null);
radius_circle = null;
}
for (i = 0; i < markers_on_map.length; i++) {
if (markers_on_map[i]) {
markers_on_map[i].setMap(null);
markers_on_map[i] = null;
}
}
if (geocoder) {
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
var address_lat_lng = results[0].geometry.location;
radius_circle = new google.maps.Circle({
center: address_lat_lng,
radius: radius_km * 1000,
clickable: false,
map: map
});
if (radius_circle) map.fitBounds(radius_circle.getBounds());
for (var j = 0; j < all_locations.length; j++) {
(function(location) {
var marker_lat_lng = new google.maps.LatLng(location.lat, location.lng);
var distance_from_location = google.maps.geometry.spherical.computeDistanceBetween(address_lat_lng, marker_lat_lng); //distance in meters between your location and the marker
if (distance_from_location <= radius_km * 1000) {
var new_marker = new google.maps.Marker({
position: marker_lat_lng,
map: map,
title: location.name
});
google.maps.event.addListener(new_marker, 'click', function() {
if (infowindow) {
infowindow.setMap(null);
infowindow = null;
}
infowindow = new google.maps.InfoWindow({
content: '<div style="color:red">' + location.name + '</div>' + " is " + distance_from_location + " meters from my location",
size: new google.maps.Size(150, 50),
pixelOffset: new google.maps.Size(0, -30),
position: marker_lat_lng,
map: map
});
});
markers_on_map.push(new_marker);
}
})(all_locations[j]);
}
} else {
alert("No results found while geocoding!");
}
} else {
alert("Geocode was not successful: " + status);
}
});
}
}
});
Ajax is an asynchronous process, so you need to send all locations as an parameter inside success callback function
Try this:
Ajax:
jQuery(function($){
$('#filter').submit(function(e){
e.preventDefault();//preventing form to submit with page reload
var filter = $('#filter');
var ajaxurl = '<?php echo admin_url("admin-ajax.php", null); ?>';
data = { action: "ek_search"};
$.ajax({
url: ajaxurl,
data:data,
async:false,
type: 'POST', // POST
dataType: 'json',
success: function(response) {
console.log(response);
showCloseLocations(response.all_locations);
}
});
return false;
});
});
Update function showCloseLocations to accept all_locations as parameter
function showCloseLocations(all_locations) {
//show location function code here
}
Question: I would like to know how you are submitting your form with #filter? because there is no submit type button in your html, make sure to change type of search button to submit instead of button so that first form can submit with search input to get all locations
<button type="submit">Search</button>

Refresh JavaScript and Ajax call to controller after 3 seconds without any click in Razor View in MVC 4

Controller Action :
public ActionResult googlemap()
{
return View();
}
It will call the googlemap.cshtml View.
So Ajax Call and JavaScript code in googlemap.cshtml View :
#{
ViewBag.Title = "Google Map";
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCM7G5ruvunb0K7qxm6jb1TssJUwROqs-g" type="text/javascript"></script>
<script type="text/javascript">
var myMarkers = [];
window.onload = function () {
$.ajax({
async: false,
type: "POST",
dataType: "json",
url: '#Url.Action("googlemapfindlatlon", "Home")',
data: '{}',
success: function (data) {
$.each(data, function (i, v) {
myMarkers.push(v);
});
var mapOptions = {
center: new google.maps.LatLng(myMarkers[0].Latitude, myMarkers[0].Langitude),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//alert(myMarkers[0].Latitude)
//alert(myMarkers[0].Langitude)
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < myMarkers.length; i++) {
var data = myMarkers[i]
var myLatlng = new google.maps.LatLng(data.Latitude, data.Langitude);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.Address);
infoWindow.open(map, marker);
});
})(marker, data);
}
//map.setCenter(latlngbounds.getCenter());
//map.fitBounds(latlngbounds);
}
});
//init google map
}
</script>
<div id="map_canvas" style="border-top: none; width: 100%; margin-top: -1px;
height: 250px; background-color: #FAFAFA; margin-top: 0px;">
</div>
Action in Controller :
public JsonResult googlemapfindlatlon()
{
Models.Vehicle_Tracking_SystemEntities entities = new Vehicle_Tracking_SystemEntities();
var latlon = entities.LatLangs.ToList();
//var latlon = entities.LatLangs.OrderByDescending(x => x.Id).Take(1).ToList();
return Json(latlon, JsonRequestBehavior.AllowGet);
}
So here I wants that my Ajax call is done repeatedly after each 3 seconds automatically to the JsonResult action in controller , and controller get the latest values and send back to the Ajax.
var myMarkers = [];
window.onload = function () {
DisplayMap();
}
function DisplayMap() {
$.ajax({
async: false,
type: "POST",
dataType: "json",
url: '#Url.Action("googlemapfindlatlon", "Home")',
data: '{}',
success: function (data) {
$.each(data, function (i, v) {
myMarkers.push(v);
});
var mapOptions = {
center: new google.maps.LatLng(myMarkers[0].Latitude, myMarkers[0].Langitude),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//alert(myMarkers[0].Latitude)
//alert(myMarkers[0].Langitude)
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < myMarkers.length; i++) {
var data = myMarkers[i]
var myLatlng = new google.maps.LatLng(data.Latitude, data.Langitude);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.Address);
infoWindow.open(map, marker);
});
})(marker, data);
}
//map.setCenter(latlngbounds.getCenter());
//map.fitBounds(latlngbounds);
}
});
//init google map
}
setTimeout(function () {
DisplayMap();
}, 3000);// JavaScript source code
Try this:
var searchActiveTVInterval = null;
$(document).ready(function () {
clearInterval(searchActiveTVInterval);
searchActiveTVInterval = setInterval("SearchActiveTV()", 3000);
});
function SearchActiveTV() {
console.log(1);
//your AJAX Call
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
window.setInterval(function(){
/// call your ajax function here
}, 3000);

How to add pins to google map using jQuery and JSON

I am trying to add pins to a Google Map using postcodes stored in a Google Sheet. So far I have been able to access to the Postcodes in the spreadsheet using JSON:
$.getJSON('http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/od6/public/values?alt=json', function(data) {
$.each(data.feed.entry, function(i, v) {
var data = $('<div class="listing">').append('<h4 id="bandb">' + v.gsx$postcode.$t + '</h4>');
$('body').append(data);
});
});
I am also able to add pins to a Google Map using the postcodes.
Example: http://codepen.io/aljohnstone/pen/eJOyrP
I am having trouble combining the two. I would like the postcodes variable in the Codepen to take the postcodes from my Google Sheet.
Working example using the Google Maps Javascript API v3:
$(document).ready(function() {
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById("map_canvas"), {
center: {
lat: 54,
lng: -3
},
zoom: 5
});
var i;
var postcodes = [];
$.getJSON('http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/od6/public/values?alt=json', function(data) {
$.each(data.feed.entry, function(i, v) {
postcodes.push(v.gsx$postcode.$t);
});
}).done(function() {
map.setCenter(new google.maps.LatLng(54.00, -3.00));
map.setZoom(5);
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < postcodes.length; i++) {
geocoder.geocode({
'address': "" + postcodes[i]
}, (function(i) {
return function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: postcodes[i]
});
bounds.extend(marker.getPosition());
map.fitBounds(bounds);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
}
})(i));
}
});
});
html,
body,
#map_canvas {
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js" type="text/javascript"></script>
<div id="map_canvas"></div>
Try this
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false" type="text/javascript"></script>
<div id="map_canvas" style="width: 600px; height: 350px"></div>
<script type="text/javascript">
$(document).ready(function()
{
var geocoder = new GClientGeocoder();
var map = new GMap2(document.getElementById("map_canvas"));
var i;
var postcodes = [];
$.getJSON('http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/od6/public/values?alt=json', function(data) {
$.each(data.feed.entry, function(i, v)
{
postcodes.push(v.gsx$postcode.$t);
});
}).done(function()
{
map.setCenter(new GLatLng(54.00, -3.00), 5);
for (i = 0; i < postcodes.length; i++) {
geocoder.getLatLng(postcodes[i] + ', UK', function(point) {
if (point) {
map.addOverlay(new GMarker(point));
}
});
}
});
});
</script>
Working example http://codepen.io/snm/pen/eJOVMY?editors=101

Remove marker based on location

I'm trying to remove a marker on my map based on it's address but it's not working for some reason. It must be something obvious that i'm not seeing. It's not going into the if(m==locationsall[i][0]) in the deleteMarker method even though i've ensured that m and locationsall[i][0] are identical.
//alert(tmp);
//alert(locationsall[0][0]);
Adding to map code:
$('#map').show();
var geocoder = new google.maps.Geocoder();
var address = document.getElementById("address").value +", " + document.getElementById("city").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
locationsall[counter] = new Array();
locationsall[counter][0] = address;
locationsall[counter][1] = lat;
locationsall[counter][2] = lng;
var mapOptions = {
zoom: 13,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var i;
for (i = 0; i < locationsall.length; i++) {
locationsall[i][3] = marker = new google.maps.Marker({
position: new google.maps.LatLng(locationsall[i][1], locationsall[i][2]),
map: map
});
//markersArray.push(marker);
}
counter++;
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
Code that retrieves the address from a textbox and formats it to '1 main street, city'
var tmp = locations.splice(locations.indexOf(location), 1);
deleteMarker(tmp);
Delete marker code:
function deleteMarker(m){
for (i = 0; i < locationsall.length; i++) {
if(m==locationsall[i][0]){
alert(locationsall[i][0]);
alert(locationsall[i][3]);
locationsall[i][3].setMap(null);
}
}
}
Turns out I had an extra space when I compared m and locationsall[i][0];
The code works perfectly now.

Categories