I am drawing markers that represent shops on a map.
There is a single global infoWindow which appears for each marker that is clicked, right after it closes for the previous clicked marker.
In some cases a few shops may have the same address so the markers appear on top of each other and one can only see the top marker.
To solve this I added pagination to the infoWindow.
The problem is that the top marker is the last one on the list, and so the infoWindow shows the latest shop's info and the pagination shows the "back" button, instead of showing the first shop first and the "next" button.
I tried reversing the order of the "for" loop like this for (i=limit; i>0; i--) but it doesn't work. The map gets stuck as if running some ajax request.
Here's the code:
function drawShopsMarkers(){
var marker;
markersArray = [];
var i;
var limit = globalShopsArr.length;
for (i=0; i<limit; i++){
marker = new google.maps.Marker({
position: new google.maps.LatLng(globalShopsArr[i].shopLat, globalShopsArr[i].shopLng),
map: map,
title: globalShopsArr[i].shopTitle
});
markersArray.push(marker);
marker.setMap(map);
google.maps.event.addListener(markersArray[i], 'click', makeListener(i));
}
function makeListener(index) {
return function() {
globalInfowindow.disableAutoPan=true;
globalInfowindow.open(map,markersArray[index]);
CreateInfoWindowString(index);
globalInfowindow.setOptions({
content: globalContentString
});
}
}
}
The CreateInfoWindowString() function simply populates the globalContentString including the pagination.
Can you say what's causing the problem?
Try
for (i=limit-1;i>=0;i--)
like suggested in the comment. You need to change the line when you attach the function to the marker, too. When you push the marker to the array it's accumulate but you attach function to a non-existent element. Use another variable and increment it in the loop: c++
This line google.maps.event.addListener(markersArray[i],.. ... ...
When you change the loop to decrement i and try markersArray[i] it must give an error because element i isn't in the array yet. So create a c variable and use it instead like I wrote and change the line to use c instead of i.
Related
I am using ACF's Google Map to load a map on my page. I pretty much copied everything exactly and slightly modifying the map js with more options on it for styling purposes. I had to change mainly this part in order for the map to load:
$('a[href="#directions"]').on('shown.bs.tab',function(){
$('.hotel-map').each(function(){
// create map
map = new_map( $(this) );
google.maps.event.trigger(map, 'resize');
});
});
Using their doc ready wasn't working, the map would appear as a grey box. The code change above produces a map, however, once I click onto another tab and then back onto the tab that holds the map, the longitude and latitude seems to disappear. It loads a map that is somewhere way off.
Here's the full js code.
EDIT
This is what I updated the code to:
$(document).ready(function(){
$('.hotel-map').each(function(){
// create map
map = new_map( $(this) );
});
});
$('a[href="#directions"]').on('shown.bs.tab',function(){
// popup is shown and map is not visible
google.maps.event.trigger(map, 'resize');
center_map( map );
});
After you have triggered the map resize call the center_map(map); function (which is in the code you linked) which will center the map to your markers.
I am trying to build something similar to this example.
The example's workflow is the following:
add 2 markers to map.
click "get route"
keep clicking forward until you get from point A to point B
If a user inserts a third marker -> click get route etc, original route gets redrawn.
What I want to achieve is the following. I have a fixed destination, and user inserts one marker, clicks get_route, then forward until route gets drawn, one step at a time. So far so good.
I have made it possible for the user to add a second marker, click get route, and see the route drawn to the destination.
The problem I am facing is the following. On the second marker, the first time the user clicks forward, he gets two steps at once drawn, after that another two, etc. The third marker, 3steps per click. 4th marker, 4 steps per click, etc.
Here is the code:
$(document).ready(function(){
$('#forward').attr('disabled', 'disabled');
$('#back').attr('disabled', 'disabled');
$('#get_route').click(function(e){
e.preventDefault();
count = 0;
map.getRoutes({
origin: [map.markers[map.markers.length-1].getPosition().lat(), map.markers[map.markers.length-1].getPosition().lng()],
destination: [meetinglat, meetinglng],
travelMode : google.maps.TravelMode.WALKING,
callback: function(e){
route = new GMaps.Route({
map: map,
route: e[e.length-1], // e[0] initially
strokeColor: '#336699',
strokeOpacity: 0.5,
strokeWeight: 10,
destination: [meetinglat, meetinglng]
});
$('#forward').removeAttr('disabled');
$('#back').removeAttr('disabled');
}
});
$('#forward').click(function(e){
e.preventDefault();
route.forward();
if(route.step_count <= route.steps_length && count < route.steps_length){
count++;
$('#steps').append('<li>'+route.step_count+' '+route.steps[route.step_count-1].instructions+'</li>');
$("#container").scrollTop($("#container")[0].scrollHeight);
}
});
$('#back').click(function(e){
e.preventDefault();
route.back();
if(route.step_count >= 0){
$('#steps').find('li').last().remove();
count--;
}
});
});
map = new GMaps({
el: '#map',
lat: meetinglat,
lng: meetinglng,
zoom: 17,
height: '500px',
click: function(e){
map.addMarker({
lat: e.latLng.lat(),
lng: e.latLng.lng()
});
}
});
Can you tell if I am missing something here? When a new route gets created, I am passing the correct one obviously, as it is the one that gets drawn.
The problem is on the first time the user clicks "forward" after inserting the second marker, because the 2 steps run at once. The third time, 3 steps, 4th time 4 steps, etc.
Thanks very much
Edit: jsBin
Managed to resolve the issue.
It seems that "forward" and "back" click events were bubbling-propagation, so that was the reason for the behaviour it had. (1 step per click 1st marker, 2 step per click 2nd marker, 3 step per click 3rd marker etc).
I added:
e.stopImmediatePropagation();
at the end of both forward and back click event handlers. Working as expected now
The marker.setMap(null) call doesn't remove the marker from the map.
I have confirmed the map and marker vars point to the right place but the setMap(null) call simply leaves the marker visible on the map. The setVisible(false) also has no effect.
if(sch_ovr_google_markers.length > 0){//remove from map
for(var i=0;i < sch_ovr_google_markers.length;i++){
sch_ovr_google_markers[i].setMap(null);//no effect
}
}
The markers are created here:
var latlon = new google.maps.LatLng(o.lat, o.lon);
var marker = new google.maps.Marker(
{
map:sch_google_map,
position: latlon,
title: gpn[4],
icon: pinImage,
shadow: pinShadow,
animation: google.maps.Animation.DROP,
zIndex:10000,
index: c
});
sch_ovr_google_markers[lidx] = marker;
sch_ovr_google_iws[lidx] = new google.maps.InfoWindow({ content:h, position:latlon });
sch_ovr_google_cbs[lidx] = sch_ovr_google_marker_init(marker,lidx);
The whole map works great except for this one problem. The surrounding code tests good and too involved to list completely.
I am wondering if there is some hidden preconditions for it to work. I have tried deleting other references to it before setMap(null), but still no luck.
The documentation makes it sound like the method will simply remove it, but obviously, to met at least, there is something more required. Any ideas?
Hopefully the original poster still isn't needing this late answer, but I had similar symptoms and couldn't find any help in the Internets.
For me, there was a problem in populating the data which caused duplicate markers to appear. Therefore, calling setMap(null) didn't seem to do anything, though it still actually did work ok, but of course it only worked on the other marker, leaving the other still on the map which looked like the setMap(null) isn't working.
So, if you're sure that your marker's map is set to null (you can check from javascript console/debugger) but the marker is still visible, try setting draggable: true parameter for the marker and move it around to see if another marker is lurking behind it.
What I would like to do is create a map after an element is clicked on. I'm using Google Maps v3.
I have a Realty listing page that shows 15 results/properties per page. Instead of generating 15 maps I would like 1 map to be created when I click on an element. Once clicked on, the map generation process takes place. The map canvas/div is initially hidden.
I was thinking that the click element and map element relationship would be something like this:
<span id="12-1234" lat="10.101010" lng="-25.252525" class="view-map">View Map</span>
... other markup ...
<div id="12-1234-map" class="google-map"></div>
Using HTML5 I add custom attributes to the element about the property like id, latitude and longitude so I can change the icon and center the map.
I've got a functioning map from which I load markers from a dynamically generated XML file based on the search parameters.
I've been looking at addListener and addDomListener but haven't had any luck. Most searches just pull up issues related to markers.
I had a wonky thing that sort of worked that used jQuery. Something like this:
$('.view-map').click(function(){
google.maps.event.addDomListener( this, 'click', initialize );
$("#" + this.id + "-map").toggle();
});
Obviously this wasn't perfect as you'd have to click the element a couple more times before seeing the map as you've bound another click event to it after having already clicking on it.
I feel like I'm missing something obvious.
function initialize(link) {
var mapDiv = $('#' + link.attr('id') + '-map');
mapDiv.toggle();
var options = {
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(link.attr('lat'), link.attr('lng'))
};
var map = new google.maps.Map(mapDiv[0], options);
}
$('.view-map').click(function(){
initialize(this);
});
In your view-map click function, just call a map initialize method, passing in the appropriate values. This initialize function can then show the map div, and then initialize the map appropriately.
Ugly and unchecked example:
var params = {
lat : 47.5,
lng : -122.5 }
$('.view-map').click(params, function(){
params.id = this.id //e.g. 1234
initialize(params);
});
function initialize(params){
// show the 1234-map div, initialize the map
}
I need some help with JavaScript and Google Maps API.
I have a Google Maps map on my website which shows markers, which in turn show a custom InfoBox when clicked on.
When a marker is clicked, a new object is created for this InfoBox:
google.maps.event.addListener(marker, 'click', function() {
infoBox = new InfoBox({id: id, content: description, latlng: marker.getPosition(), map: map});
});
When a visitor clicks two markers consecutively, he is faced with two InfoBoxs. I run two lines of code that hide the InfoBoxs when a users clicks away in the map or when they click the cross in the upper right corner:
google.maps.event.addDomListener(closeImg, 'click', removeInfoBox(this));
google.maps.event.addDomListener(map, 'click', removeInfoBox(this));
What I would like to happen is that when a user clicks on a marker, all previous markers will get hidden (so after each click on a marker, there would only be one previous InfoBox to be hidden).
I'm struggling to get this done. If I create a DomListener on all markers with the 'click' event, I never get an InfoBox to pop up. If I put removeInfoBox(this); before creating a new object of InfoBox I also never get shown an InfoBox.
Where and how would be the proper way to prevent more than one InfoBox from showing up?
I found a post on how to remove markers and keep track of them which I could adept to my script.
First I declare the array for storing opened infoBox'es and the function to remove them (clearOverlays()):
// Declare global array for hiding infowindows
var infowindowsArray = [];
function clearOverlays(){
if(infowindowsArray){
for (i in infowindowsArray){
infowindowsArray[i].setMap(null);
}
}
}
Then when I create a listener for the marker's click event, it will add the new infoBox to that marker. First I use the clearOverlays() function to clear all other infoBox'es. Then I create the new infoBox and push it into the array:
google.maps.event.addListener(marker, 'click', function() {
clearOverlays();
infoBox = new InfoBox({id: id, content: description, latlng: marker.getPosition(), map: map});
infowindowsArray.push(infoBox);
});
This solved my problem with the custom created infoBox'es.