I work in Laravel project and I have module for displaying and removing all stores on a Google map if I choose only 1 store.
This is a duplicate question, however, why my function is not working setting the function showallmarks as null.
Question: How to remove all the marks displayed in the google maps once a button is clicked?
I have here the codes.
Show all marks:
showallmarks();
function showallmarks() {
$.each(locations, function(index, value) {
var position = new google.maps.LatLng(value.store_lat, value.store_long);
var title = value.branch_name;
var address = value.store_address;
var contentString = "<h5>" + title + "</h5>" + address;
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: position,
icon: google.maps.marker,
map: map,
zoom: 12
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
});
}
Once I click this button the showallmarks must not be shown on the Google map.
var markeronce;
$('button#addresses').click(function() {
//removing all marks
showallmarks(null);
var infowindow = new google.maps.InfoWindow({
content: "<span>Visit us on our store.</span>"
});
var address_href = $(this).val();
var commaPos = address_href.indexOf(',');
var coordinatesLat = parseFloat(address_href.substring(0, commaPos));
var coordinatesLong = parseFloat(address_href.substring(commaPos + 1, address_href.length));
var centerPoint = new google.maps.LatLng(coordinatesLat, coordinatesLong);
if (!markeronce) {
markeronce = new google.maps.Marker({
position: centerPoint,
map: map,
zoom: 8
});
} else {
markeronce.setPosition(centerPoint);
}
map.setCenter(centerPoint);
})
Add Button like
<input type="button" value="Delete" onclick="DeleteMarkers()" />
And try this function
<script type="text/javascript">
var markers = [];
function DeleteMarkers() {
//Loop through all the markers and remove
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
};
</script>
Related
I have been working on this for a while now. I have looked at multiple stack overflow posts on the topic and several tutorials, but I have not been able to get infoWindow.close() to work.
I have even tried using jQuery to click $('#googleMap > div > div > div:nth-child(1) > div:nth-child(4) > div:nth-child(4) > div:nth-child(1) > div:nth-child(3)').click(); which actually seems to work in the browser console, but not when running the click listener.
Any suggestions or directions are much appreciated.
d3.csv('/data/locs.csv', function(locs){
var obj = [];
for(i=0;i<locs.length;i++) {
var country = locs[i].country;
var location = locs[i].location;
var lat = locs[i].lat;
var long = locs[i].long;
var description = locs[i].description;
obj.push({
con: country,
location: location,
lat: lat,
lng: long,
description: description
});
}
console.log(obj);
initMap(obj)
});
function initMap(obj, error) {
if (error){console.log("Error: "+error)}
var openInfoWindow = null;
var mapProp = {
center: {lat: 39.8283, lng: -98.5795},
zoom: 2
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var pointLoc = [];
var labels = [];
var descrip = [];
var locale = [];
for(i=0;i<obj.length;i++) {
pointLoc.push({lat: obj[i].lat, lng: obj[i].lng});
labels.push(obj[i].con);
descrip.push(obj[i].description);
locale.push(obj[i].location);
}
map.data.loadGeoJson();
for (var i = 0; i < pointLoc.length; i++) {
var coords = pointLoc[i];
var latLng = new google.maps.LatLng(coords.lat,coords.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
var contentStr = '<div id="popcontent">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">'+descrip[i]+'</h1>'+
'<p>'+locale[i]+', '+labels[i]+'</p>' +
'</div>';
var infoWindow = new google.maps.InfoWindow({
maxWidth: 300
});
google.maps.event.addListener(marker,'click', (function(marker,contentStr,infowindow){
infowindow.close();
return function() {
infowindow.setContent(contentStr);
infowindow.open(map, marker);
};
})(marker,contentStr,infoWindow));
}
}
Stephen's answer identifies the problem with the infowindow. I want to help you learn to write simpler code.
There is a lot of complication in this code that you don't need; in fact you can get rid of most of the code!
The code first converts the locs array to a very similar obj array that has a couple of fields renamed.
Then it converts this obj array to four individual arrays pointLoc, labels, descrip, and locale.
None of this conversion is needed.
Also, when naming an array, I recommend using a plural name for the array and the singular form of that name for an element of the array. You did this in some places, just not consistently.
There is a map.data.loadGeoJson(); call that doesn't do anything because no URL is provided.
You also don't need the function-that-returns-a-function in the click listener, if you provide a closure in a simpler way as in the code below.
Here's an example of how you could do the whole thing in a much simpler manner:
d3.csv( '/data/locs.csv', function( places ) {
var infoWindow;
var map = new google.maps.Map( document.getElementById('googleMap'), {
center: { lat: 39.8283, lng: -98.5795 },
zoom: 2
});
places.forEach( function( place ) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng( place.lat, place.long ),
map: map
});
google.maps.event.addListener( marker, 'click', function() {
if( infoWindow ) infoWindow.close();
var content =
'<div id="popcontent">' +
'<div id="siteNotice">' +
'</div>' +
'<h1 id="firstHeading" class="firstHeading">' + place.description + '</h1>' +
'<p>' + place.location + ', ' + place.country + '</p>' +
'</div>';
infoWindow = new google.maps.InfoWindow({
maxWidth: 300,
content: content
});
infoWindow.open( map, marker );
});
});
});
Your variable infoWindow goes out of scope when returning a function, and you not modifying the outer infoWindow, but the one passed into the function. Try this.
d3.csv('/data/locs.csv', function(locs){
var obj = [];
for(i=0;i<locs.length;i++) {
var country = locs[i].country;
var location = locs[i].location;
var lat = locs[i].lat;
var long = locs[i].long;
var description = locs[i].description;
obj.push({
con: country,
location: location,
lat: lat,
lng: long,
description: description
});
}
console.log(obj);
initMap(obj)
});
function initMap(obj, error) {
if (error){console.log("Error: "+error)}
var openInfoWindow = null;
var mapProp = {
center: {lat: 39.8283, lng: -98.5795},
zoom: 2
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var pointLoc = [];
var labels = [];
var descrip = [];
var locale = [];
for(i=0;i<obj.length;i++) {
pointLoc.push({lat: obj[i].lat, lng: obj[i].lng});
labels.push(obj[i].con);
descrip.push(obj[i].description);
locale.push(obj[i].location);
}
map.data.loadGeoJson();
for (var i = 0; i < pointLoc.length; i++) {
var coords = pointLoc[i];
var latLng = new google.maps.LatLng(coords.lat,coords.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
var contentStr = '<div id="popcontent">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">'+descrip[i]+'</h1>'+
'<p>'+locale[i]+', '+labels[i]+'</p>' +
'</div>';
var infoWindow = new google.maps.InfoWindow({
maxWidth: 300
});
google.maps.event.addListener(marker,'click', (function(marker,contentStr,infowindow){
infowindow.close();
return((function(infowindow) {
infowindow.setContent(contentStr);
infowindow.open(map, marker);
})(infowindow));
})(marker,contentStr,infoWindow));
}
}
I was able to handle it easily with jQuery trigger event.
jQuery('.gm-ui-hover-effect').trigger('click');
Just put above code inside addListener function of marker and don't forget to include jQuery in your script.
I have an array like this deviceId = [005305230001JIZZZZ, 085835360001NBGJZZ, 085835360002NBGJZZ].
The info window should show the deviceId and be displayed based on which marker is clicked. I started looking at JavaScript only a few days back and can't understand how the functions work and dont have the time right now to learn becauseI have to get this done. I saw a few implementations on this, but I think they have done the adding multiple markers differently using functions, I think. I couldn't understand it so I used for loop.
The latArray and lngArray have something like this [12.1456,12.5256,11.566] and [72.145,72.4557,75.23535]
I cant figure out how to add info windows for corresponding markers.
This is the code for map:
function initMap() {
var bounds = new google.maps.LatLngBounds();
var mapDiv = document.getElementById('map');
var map = new google.maps.Map(mapDiv);
map.setCenter(new google.maps.LatLng(latArray[0],lngArray[0]));
map.setZoom(18);
for(i=0;i<latArray.length;i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(latArray[i],lngArray[i]),
map: map,
title:"This is the place.",
// icon:"phone4.png"
});
//bounds.extend(marker.getPosition());
console.log(latArray);
console.log(lngArray);
}
//map.fitBounds(bounds);
var infoWindow = new google.maps.InfoWindow({
content: contentString
});
marker.addListener('click', function() {
infoWindow.open(map, marker);
});
}
How to show info window of corresponding markers.
This is content for marker:
contentString = '<div id = "content>'
+'<p style = "color:#000000">DeviceID<p>' +
'<p>'+ deviceId[i] + '<br></p>' //deviceId is the array with content
+ '</div>'
I read something about closures but didn't understand. Please help
Edit: I just tried this. I'm getting js?callback=initMap:34 InvalidValueError: setPosition: not a LatLng or LatLngLiteral: not an Object
What i tried:
var markerArray=[];
for(i=0;i<latArray.length;i++)
{
markerArray.push("new google.maps.LatLng("+ latArray[i]+","+lngArray[i]+")");
console.log(markerArray[i]);
}
console.log(markerArray[0]);
for(i=0;i<latArray.length;i++)
{
marker = new google.maps.Marker({
position: markerArray[i],
map: map,
title:"This is the place.",
// icon:"phone4.png"
});
var infoWindow = new google.maps.InfoWindow({
content: contentString[i]
});
marker.addListener('click', function(marker,contentString) {
infoWindow.open(map, marker);
});
}
So I will not bother you with the explanation how closures work (as you are saying your not interested in it now), I just supply you the solution:
// Your arrays with geo informations
var latArray = [-25.363, -26.263, -25.163];
var lngArray = [131.044, 131.144, 132.044];
// Your array with device information
var deviceIdArray = ["AAA", "BBB", "CCC"];
// Just create map according to the first geo info
var map = new google.maps.Map(document.getElementById("map"), {
center: {lat: latArray[0], lng: lngArray[0]},
zoom: 6
});
// Loop throuhg all geo info
latArray.forEach(function(lat, i) {
// For each one create info window
var infoWindow = new google.maps.InfoWindow({
content: '<div id="content>'
+ '<p style="color:#000000">DeviceID<p>'
+ '<p>'+ deviceIdArray[i] + '</p>'
+'</div>'
});
// For each one create marker
var marker = new google.maps.Marker({
map: map,
position: {lat: latArray[i], lng: lngArray[i]}
});
// Click on the currently created marker will show the right info window
marker.addListener("click", function() {
infoWindow.open(map, marker);
});
});
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map"></div>
Take a look at my function with map. It takes json object with some data from PHP and 'translate' it into array and then adds content to multiple markers (it is not dynamic in real time - you have to reload page). In addition it has a search box (which opens certain info window). If you don't understand do not hestitate to ask :).
//check if document is fully loaded, seetting a container for ajax call results
$(document).ready(function() {
var tablica = [];
// ajax call for action preparing set of names, descriptions, coords and slugs needed to render deatiled markers on map
$.ajax({
url: 'map/json_prepare',
dataType: 'json',
success: function(response) {
var obj = JSON && JSON.parse(response) || $.parseJSON(response);
obj.forEach(function(item, index, array)
{
tablica.push(item);
});
//call a function rendering a map itself
var map;
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.06561980, lng: 19.946850},
zoom: 12
});
////////////////////////////////////////////////////////////////////////////////////////////////////
// LOOP ADDING MARKERS FROM DB WITH PROPER INFO WINDOWS (DESCRIPTION AND LINKS)
// Add a markers reference
var markers = [];
$.each(tablica, function( key, value ) {
//markers
var myLatLng = {lat: value[1], lng: value[2]};
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: value[0],
clickable: true,
animation: google.maps.Animation.DROP,
adress: value[5]
});
//infowindows
marker.info = new google.maps.InfoWindow ({
content: '<h1>'+ value[0] + '</h1>' + '<br>' + '<br>' + value[3] + '<br>' + value[5] +'<br>' + '<br>' + '' + 'Details' + '<br/>' +
'' + 'Take part in' + '<br>'
});
//eventlistener - after click infowindow opens
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
//event listener - after dblclick zoom on certain event is set
google.maps.event.addListener(marker, 'dblclick', function() {
map.setZoom(18);
map.setCenter(marker.getPosition());
});
markers.push(marker);
});
// End of loop adding markers from db.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///additional event listener - rightclick to get back default zoom
google.maps.event.addListener(map, 'rightclick', function() {
map.setZoom(12);
map.setCenter(map.getPosition());
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CENTRING MAP AS ALL OF MARKERS IS VISIBLE//
//create empty LatLngBounds object
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < tablica.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(tablica[i][1], tablica[i][2]),
map: map
});
//extend the bounds to include each marker's position
bounds.extend(marker.position);
}
//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
///SEARCH_BOX////////
///Here comes part of script adding search box
// Create the search box and link it to the UI element.
// Anchor search box and search button to the map.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
var button = document.getElementById('submitSearch');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(button);
//replacing polish characters on order to search without necessity typing them
function cleanUpSpecialChars(str)
{
str = str.replace(/[Ą]/g,"A");
str = str.replace(/[ą]/g,"a");
str = str.replace(/[Ę]/g,"E");
str = str.replace(/[ę]/g,"e");
str = str.replace(/[Ć]/g,"C");
str = str.replace(/[ć]/g,"c");
str = str.replace(/[Ł]/g,"L");
str = str.replace(/[ł]/g,"l");
str = str.replace(/[Ń]/g,"N");
str = str.replace(/[ń]/g,"n");
str = str.replace(/[Ó]/g,"O");
str = str.replace(/[ó]/g,"o");
str = str.replace(/[Ś]/g,"S");
str = str.replace(/[ś]/g,"s");
str = str.replace(/[Ź]/g,"Z");
str = str.replace(/[ź]/g,"z");
str = str.replace(/[Ż]/g,"Z");
str = str.replace(/[ż]/g,"z");
return str;
}
//Function, that search in array of markers, one which fits the key word written in searchbox.
$('#submitSearch').click(function() {
//Catching searched word and preparing its value for search process
var toSearch = $(input).val().trim();
toSearch = cleanUpSpecialChars(toSearch);
toSearch = toSearch.toLowerCase();
console.log('Szukana fraza -> ' + toSearch);
var results = [];
if (toSearch.length >=3) {
// Iterate through the array
$.each(markers, function (i, marker) {
//preparing certain elemnts of marker objects for search process
markers[i].title = cleanUpSpecialChars(markers[i].title);
markers[i].adress = cleanUpSpecialChars(markers[i].adress);
markers[i].title = markers[i].title.toLowerCase();
markers[i].adress = markers[i].adress.toLowerCase();
if (markers[i].title.indexOf(toSearch) > -1 || markers[i].adress.indexOf(toSearch) > -1) {
results.push(markers[i]);
}
});
if (results.length < 1) {
console.log ('nic');
$('#message2').slideDown(500, function () {
setTimeout(function () {
$('#message2').slideUp(500);
}, 5000);
});
}
// Close all the infoWindows, before rendering Search results.
markers.forEach(function (marker) {
marker.info.close(map, marker);
});
//Opens infWindows for multiple markers found and set bounds so that all markers found are visible
results.forEach(function (result) {
result.info.open(map, result);
bounds.extend(result.position);
});
map.fitBounds(bounds);
}
else{
//what if user has typed less than three characters in searchbox -> render flash mess.
$("#message").slideDown(500, function(){
setTimeout(function(){
$("#message").slideUp(500);
},5000);
});
}
});
//Enabling key Enter for triggering a search action.
$(input).keypress(function(e){
if(e.which == 13){//Enter key pressed
$('#submitSearch').click();//Trigger search button click event
}
});
},
//////////////////////////////////////////////////////////////////////////////////////////
//obsługa błędu, jeśli nie zostanie wyświetlona mapa
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status);
console.log(thrownError);
console.log(ajaxOptions);
alert('Map is broken. Please try again later.')
}
});
});
It will not qork here because it doesn't contain data from php.
Using Google Maps API to add an infoWindow to each marker. Markers come from an array.
Although, infoWindow only shows up for the first marker, not the others. Why? Thanks.
function set_markers(array) {
var mapOptions = {
zoom: 13
}
for (var i = 0; i < array.length; i++) {
var single_location = array[i];
var myLatLng = new google.maps.LatLng(single_location[1], single_location[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: single_location[0]
});
var infowindow = new google.maps.InfoWindow({
content: ""
});
}
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<h3>'+this.title+'</h3>');
infowindow.open(map,this);
});
}
var infowindow = new google.maps.InfoWindow();
function set_markers(array) {
var mapOptions = {
zoom: 13
};
for (var i = 0; i < array.length; i++) {
var single_location = array[i];
var myLatLng = new google.maps.LatLng(single_location[1], single_location[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: single_location[0]
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent('<h3>' + this.title + '</h3>');
infowindow.open(map, this);
});
}
}
This is untested since you didn't post a MCVE.
I have a map with multiple polylines which I am looking to display infowindow for each line. I have the infowindow working but it is not positioning to the event click as it should be. Instead, each window displays in the same place. Can't seem to track down the root of the issue.
<script type="text/javascript">
var contentString = "";
var infowindow = new google.maps.InfoWindow({
content: contentString,
});
function initialize() {
var myLatlng = new google.maps.LatLng(30.695895, -97.354080);
var mapOptions = {
zoom: 5,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.TERRAIN,
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
downloadUrl("data.xml", function(data) {
var xml = xmlParse(data);
var polylines = xml.documentElement.getElementsByTagName("polyline");
var polylineData = new Array();
for (var i = 0; i < polylines.length; i++) {
polylineData[i] = {id:polylines[i].getAttribute("id"),
name:polylines[i].getAttribute("name"),
olat:polylines[i].getAttribute("olat"),
olng:polylines[i].getAttribute("olng"),
dlat:polylines[i].getAttribute("dlat"),
dlng:polylines[i].getAttribute("dlng")}
}
for (var j = 0; j < polylineData.length; j++) {
var path = [
new google.maps.LatLng(parseFloat(polylineData[j].olat), parseFloat(polylineData[j].olng)),
new google.maps.LatLng(parseFloat(polylineData[j].dlat), parseFloat(polylineData[j].dlng))
];
var polyline = new google.maps.Polyline({
path: path,
strokeWeight: 2
});
google.maps.event.addListener(polyline, 'click', (function(event,index){
return function(){
infowindow.content = '<div class="infobox" style="width:280px;"><span class="name">' + polylineData[index].name + '</span></div>';
var point = event.latLng;
infowindow.setPosition(point);
infowindow.open(map);
};
})(event,j));
polyline.setMap(map);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
XML data looks like this:
<polylines>
<polyline id="176" name="Line Name" olat="53.545204" olng="-113.369492" dlat="53.545204" dlng="-113.369492"/>
</polylines>
I have read some similar posts but none of the answers have worked in this case thus far. Thanks!
event must be the argument passed to the returned function:
google.maps.event.addListener(polyline, 'click', (function(index){
//_________________________________________________________^:the index of the item
return function(event){
//________________^:the event
infowindow.content = '<div class="infobox" style="width:280px;"><span class="name">' + polylineData[index].name + '</span></div>';
var point = event.latLng;
infowindow.setPosition(point);
infowindow.open(map);
};
})(j));
Trying to simplify my google maps custom code to put markers and an info bubble. However have run into a few issues which I can't seem to debug the code is below, it's currently outputting nothing. The code defines lat/long/title and content and then trys to ouput them as markers on a map.
<script type="text/javascript">
function initialize() {
var myLatlng = new google.maps.LatLng(20,0);
var myOptions = {
zoom: 2,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.TERRAIN
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var countries = [
{title:'Afghanistan', lat:34.28, lon:69.11, content:"<h2>Afghanistan</h2><p>16 Alumni</p>"},
{title:'Albania', lat:41.18, lon:19.49, content:"<h2>Albania</h2><p>7 Alumni</p>"},
{title:'Angola', lat:-8.5, lon:13.15, content:"<h2>Angola</h2><p>9 Alumni</p>"},
{title:'Antarctica', lat:-80, lon:0, content:"<h2>Antarctica</h2><p>1 Alumnus</p>"},
{title:'Antigua & Barbuda', lat:17.20, lon:-61.48, content:"<h2>Antigua & Barbuda</h2><p>1 Alumnus</p>"},
{title:'Argentina', lat:-36.30, lon:-60, content:"<h2>Argentina</h2><p>29 Alumni</p>"},
];
for (i=0;i<countries.length;i++)
{
c = countries[i];
marker: new google.maps.Marker({position: new google.maps.LatLng(" + c['lat'] + "," + c['lon'] + "), map: map, title: '" + c['title'] + "'}),
infowindow: new google.maps.InfoWindow({content: '" + c['content'] + "'});
}
var item;
for (var i=0; i<countries.length; i++) {
item = countries[i];
google.maps.event.addListener(item.marker, 'click', makeCallback(item));
}
function makeCallback(country) {
return function () {
country.infowindow.open(map, country.marker);
};
}
}
</script>
There are various typographical and syntax errors in the code. Also there is no need to construct strings in the place of variables. The following is a working version:
...
var countries = [...];
for (var i = 0; i < countries.length; i++) {
var c = countries[i];
c.marker = new google.maps.Marker({
position: new google.maps.LatLng(c.lat, c.lon),
map: map,
title: c.title});
c.infowindow = new google.maps.InfoWindow({content: c.content});
google.maps.event.addListener(c.marker, 'click', makeCallback(c));
}
function makeCallback(country) {
return function () {
country.infowindow.open(map, country.marker);
};
}