My custom google maps code stopped working all of a sudden and I can't figure out why. If I paste the same exact code into a jsfiddle it works fine, however on my site it throws an error:
Uncaught TypeError: Object #<Object> has no method 'O'
or
Uncaught TypeError: Cannot call method 'unbindAll' of null
The pins are appearing on the map in the correct locations and respond to clicks appropriately (once) by bouncing up and down, however the popups do not pop up. What gives?
On your website, find the JavaScript code that handles the click event on one of your markers. You'll find the code in the map.html page itself:
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(37.75538, -122.201983),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i, currentMarker = "null";
for (i = 0; i < locations.length; i++) {
marker = new MarkerWithLabel({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
draggable: false,
clickable: true,
map: map,
labelContent: locations[i][3],
labelAnchor: new google.maps.Point(22, 0),
labelClass: "maplabels", // the CSS class for the label
labelStyle: {opacity: 1.0}
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
// in case they open a new info window without closing the old one, stop animation
if (currentMarker != "null")
currentMarker.setAnimation(null);
marker.setAnimation(google.maps.Animation.BOUNCE);
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
currentMarker = marker;
}
})(marker, i));
google.maps.event.addListener(infowindow, 'closeclick', function() {
currentMarker.setAnimation(null);
});
}
Now the actual code that handles the click is in the middle of that:
if (currentMarker != "null")
currentMarker.setAnimation(null);
marker.setAnimation(google.maps.Animation.BOUNCE);
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
currentMarker = marker;
Use the JavaScript debugger in Chrome or your favorite browser to set a breakpoint on the first line of this code (the if statement) by clicking in the left margin. Use the Sources tab in the developer tools to open the code.
If you aren't familiar with the JavaScript developer tools, here's an introduction to JavaScript debugging and a detailed introduction to the Chrome DevTools.
Now that you have the breakpoint set, click on one of your markers. It should stop on the line of code where you set the breakpoint.
Now use the Step Over command in the debugger to step through that code. On Windows, you can use the F10 key here. You'll see that the error happens when you try to execute this line:
infowindow.open(map, marker);
So what's wrong here? In the Chrome debugger, you can hover the mouse over any variable in the source code to see its current value.
If you look at the marker variable it looks like something fairly plausible, with properties that indeed have to do with maps and markers and such.
But take a look at the map variable. It looks like this:
Object {9: false, 16: false, 18: false, 27: false, 65: false}
That doesn't look much like a Google Maps API object, does it? In fact, some of those numbers sound very familiar. 65 is the character code for the letter 'a', 27 is Escape, and 9 is the Tab key.
It looks like somewhere else in your code, some other code has overwritten your global map variable with an unrelated variable of the same name. In fact, the name makes some sense: the map object is some sort of mapping (in the computer science sense, not the geographic sense) from character codes to booleans.
A simple fix would be to change the name of your map variable, to gmap or some other name that doesn't conflict with this other map variable. Or even better, you could wrap all of this map code inside a function so that your map variable is local to this function and won't be overwritten by a global variable elsewhere.
But it's also likely that the very existence of the other map variable is a bug! There may be some function elsewhere in the code that meant to have that map be a local variable, but simply forgot to use a var on it so it became global.
While I've got you, you can simplify that marker creation code a little by getting rid of the function-that-returns-a-function in the event handler. You're doing that to get a closure for the marker variable, but this is a needlessly complicated way to do it. Instead, you can simply put the entire body of your for loop in a function of its own. Calling that function will get you the closure you need without the extremely confusing function-returning-a-function.
Also, you don't need to use the string "null" to indicate a nonexistent currentMarker value.
And finally, you're setting an event listener on the infowindow for each marker, even though you have only one infowindow. You can set this event listener once.
Combining those ideas, you might end up with:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(37.75538, -122.201983),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(
infowindow, 'closeclick', stopAnimation
);
var currentMarker;
for (i = 0; i < locations.length; i++) {
addMarker( locations[i] );
}
function addMarker( location ) {
var marker = new MarkerWithLabel({
position: new google.maps.LatLng(location[1], location[2]),
draggable: false,
clickable: true,
map: map,
labelContent: location[3],
labelAnchor: new google.maps.Point(22, 0),
labelClass: "maplabels", // the CSS class for the label
labelStyle: {opacity: 1.0}
});
google.maps.event.addListener(marker, 'click', function() {
stopAnimation();
marker.setAnimation(google.maps.Animation.BOUNCE);
infowindow.setContent(location[0]);
infowindow.open(map, marker);
currentMarker = marker;
});
}
function stopAnimation() {
currentMarker && currentMarker.setAnimation(null);
currentMarker = null;
}
}
initMap();
Related
All,
Very simply - is there an onload handler / event for when all markers have loaded?
Eg we have 26 markers being loaded, and this is loading well before the markers:
google.maps.event.addListenerOnce(map, 'idle', function(){
// do something only the first time the map is loaded
});
Also fyi this does not work:
google.maps.event.addListenerOnce(marker,'load',function(){
// onload stuff
});
Thoughts?
Team,
Ok so I think I answered my own question - Not as elegant as I'd hoped but this works:
In our createMarker function, I added a 'checkloaded()' bit to the end, which checks if locations.length = markers.length:
function createMarker(add,lat,lng,marker_label) {
var contentString = '<div contentEditable="true">'+marker_label+'</div>';
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat,lng),
map: map,
draggable: true,
label: labels[labelIndex++ % labels.length]
});
// open marker on load
google.maps.event.trigger(marker,'click');
bounds.extend(marker.position);
//Add marker to the array.
markers.push(marker);
checkloaded();
}
And then:
function checkloaded(){
if(locations.length == markers.length){
// do onload stuff here
}
}
If there is a proper way to do that, let me know and thank you all
I have created an application for showing an Information Window popup for markers, The application is working fine and the popup is showing correctly but the only solution is that along with the custom Information Window popup when under mouse-over, default popup with html tag is showing like as shown below.
JSFiddle
Can anyone please tell me some solution for this
My code is as given below
var infowindow = new google.maps.InfoWindow();
function point(name, lat, long) {
var self = this;
self.name = name;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
title: name,
map: map,
draggable: true
});
google.maps.event.addListener(marker, 'mouseover', function () {
infowindow.setContent(marker.title);
infowindow.open(map, marker);
}.bind(this));
google.maps.event.addListener(marker, 'mouseout', function () {
infowindow.close();
}.bind(this));
}
var map = new google.maps.Map(document.getElementById('googleMap'), {
zoom: 5,
center: new google.maps.LatLng(55, 11),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var viewModel = {
points: ko.observableArray([
new point('<div>Test1<br>Test5</div>', 55, 11),
new point('Test2', 56, 12),
new point('Test3', 57, 13)])
};
function addPoint() {
console.log(viewModel.points().length);
for (var i = 0; i < viewModel.points().length; i++)
{
console.log(i);
console.log(viewModel.points().marker.title);
}
viewModel.points.push(new point('a', 58, 14));
}
ko.applyBindings(viewModel);
You could manually remove the element title attribute on mouseover.
Try changing
google.maps.event.addListener(marker, 'mouseover', function () {
To
google.maps.event.addListener(marker, 'mouseover', function (e) {
e.ya.target.removeAttribute('title');
Also for Edge, you need to be change it to:
e.ya.target.parentElement.removeAttribute('title')
JSFiddle Link (Google Maps API not working)
It appears that the title of your marker is set to the html content of your pop up window.
When you create the marker object, give it a title attribute of what you would like to be displayed (i.e. name of your location...)
var marker = new google.maps.Marker({
position: whateverpositionyouset,
title: whatevertitleyouwant,
map: map
})
I have been taking advantage of this thread in working on almost the same problem. I am able to get the Google Maps API to properly display European accented glyphs in the pop-up display when a marker is clicked, but the same encoded text string is not properly rendered on mouseover.
So, after looking at the helpful code example in JSFiddle, and not being able to use that suggested technique for removing the 'title' text, it finally became clear to me what MrUpsidown was suggesting when he thought we might just change the name of the property being displayed as a title. I did not realize that the definition of the reserved property 'title' was "text to be displayed on hover." So, the simplest solution is to use a property such as 'myTitle' in the Marker options list. When there is no title property, hovering becomes a non-event.
UPDATE
I have added the error up here as its makes it easier to read. Below is the error I now get with that update. P.S it should be InfoBox and not Infobox, I think I made that error somewhere when I typed it up :). So where am I going wrong now? I am not even sure what this error message is saying :
Uncaught TypeError: Cannot read property 'style' of null
InfoBox.setBoxStyle_
InfoBox.setOptions
(anonymous function) PAGE.php:101
N.trigger main.js:23
xK.(anonymous function).e
(anonymous function)
N.trigger main.js:23
F.ie
F.sm
(anonymous function) main.js:11
N.trigger main.js:23
F.Jk
(anonymous function)
OLD POST
I have a custom Google Maps V3 with custom markers being generated with a XML file that is built with a custom DB. I have posted my code below, this all works, only thing is I have now built in the Infobox plugin, which gives me more control over the styling of the marker styles. However they, unlike the Google InfoWindow does not close automatically when another marker is clicked.
This is my load function, which sets the map and build the marker with my XML file,
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(54.500, 355.000),
zoom: 5,
mapTypeId: 'roadmap'
});
downloadUrl("genxml.php?id=<?php echo $VarToUse ?>",function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var number = markers[i].getAttribute("number");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),parseFloat(markers[i].getAttribute("lng")));
var myOptions = {
content: "<b class=\"infoBox_links\">" + name + "</b> <br/>" + address
,disableAutoPan: false
,maxWidth: 0
,pixelOffset: new google.maps.Size(-90, -125)
,zIndex: null
,boxStyle: {
background: "#FFFFFF",
border: "1px solid grey",
width: "170px",
height: "70px",
padding: "8px",
fontSize: "12px",
overflow: "hidden"
}
,closeBoxMargin: "-5px"
,closeBoxURL: "imgs/x_google.png"
,isHidden: false
,pane: "floatPane"
,enableEventPropagation: false
};
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon
});
bindInfoWindow(marker, map, myOptions); //function call to set the markers!
}
});
} //End of function load()
As you can see I have a function that is called within the load, this is my current code, which works fine
function bindInfoWindow(marker, map, myOptions) {
google.maps.event.addListener(marker, 'click', function() {
var ib = new InfoBox(myOptions);
ib.open(map, marker);
});
} //End of bindInfoWindow function!!
This works, custom info boxes with the styles I need are generated, however the current 'open' info box does not close when a new marker is click. And from a number of different attempts and ideas from other people, I am currently working with :
function bindInfoWindow(marker, map, myOptions) {
var ibs = [];
var closeInfoBox = function() {
for (var i in ibs) {
ibs[i].close();
}
}
var ibIndex = ibs.push(new Infobox()) - 1,
ib = ibs[ibIndex];
google.maps.event.addListener(marker, 'click', function() {
closeInfoBox();
ib.setOptions(myOptions);
//var ib = new InfoBox(myOptions);
ib.open(map, marker);
});
}
This code come from Opening only a infobox at a time when multiple markers are displayed on the map
However this only gives me errors, either I have not copied this code right or my set up for the maps different enough for this code not to work (with I don't think is the case). I think it is something I am not doing right. Right now as the code stands, its this line that does not want to work,
var ibIndex = ibs.push(new Infobox()) - 1,
Comes back in the console log with
Uncaught ReferenceError: Infobox is not defined PAGE.php:101
bindInfoWindow PAGE.php:101
(anonymous function) PAGE.php:84
request.onreadystatechange
All ideas most welcome,
Many thanks
Glenn.
Try this. You need the array and closeInfoBox specified outside of the load function, otherwise you just keep resetting the array every time.
var ibs = [];
function closeInfoBox() {
for (var i in ibs) {
ibs[i].close();
}
}
And then you need to push the infobox into the array within the bind function:
function bindInfoWindow(marker, map, myOptions) {
var ib = new Infobox(myOptions);
ibs.push(ib);
google.maps.event.addListener(marker, 'click', function() {
closeInfoBox();
ib.open(map, marker);
});
}
I haven't tested this, but it's similar to what I've done in my code at various points.
However they, unlike the Google InfoWindow does not close automatically when another marker is clicked
This is new to me, a google.maps.InfoWindow will never be closed automatically .
When you only want to have a single InfoBox open use only a single InfoBox-instance for all markers:
function bindInfoWindow(marker, map, myOptions) {
google.maps.event.addListener(marker, 'click', function() {
//create a Infobox that will be used by each marker
if(!this.getMap().get('ib')){this.getMap().set('ib',new InfoBox());}
var ib = this.getMap().get('ib');
ib.setOptions(myOptions);
ib.open(this.getMap(),this);
});
}
I am pretty new to JavaScript and the google maps API. I cannot figure out what is wrong.
The InfoWindow is actually a class I found "InfoBubble".
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobubble/examples/example.html/
Here is the situation:
1. I create my map and add a 'click' event. The event creates Markers.
2. I create one global infoWindow.
3. I click the map, a Marker appears.
4. I click the map, a Marker appears.
5. I click the map, a Marker appears. Step 3-5 can be repeated lots and lots.
6. I click marker number X
6.1. An infoWindow pops up.
7. I click marker number Y
7.1. The infoWindow is closed. (.close())
7.2. Its content and position is changed
7.3. It is opened on the new position (.open(map,marker))
7.4. Also Marker number X is removed.
Try it yourself: http://dl.dropbox.com/u/6084360/test/index.html
Why is step 7.4. happening? After it has happened I can click markers however I feel like without anything disappearing. WHY?
I have tried debugging somewhat via Google Chrome but after I do step 7.3 it takes me into some minified code and I get lost.
Here is the line which removes the marker. I have no idea why it removes it or how to know where to start.
R.addDomListenerOnce=function(a,b,c,d){var e=R[yc](a,b,function(){e[wb]();return c[Cc](this,arguments)},d);return e};R.R=function(a,b,c,d){c=cf(c,d);return R[yc](a,b,c)};function cf(a,b){return function(c){return b[oc](a,c,this)}}R.bind=function(a,b,c,d){return R[G](a,b,P(c,d))};R.addListenerOnce=function(a,b,c){var d=R[G](a,b,function(){d[wb]();return c[Cc](this,arguments)});return d};R.forward=function(a,b,c){return R[G](a,b,df(b,c))};R.ua=function(a,b,c,d){return R[yc](a,b,df(b,c,!d))};
My code:
var times = 0;
var treasureLocation = new google.maps.LatLng(62.05350309096103, 15.373047874999997);
var map, infoBubble = null;
function initialize()
{
// Create the actual map.
map = new google.maps.Map(document.getElementById("map_canvas"),
{
zoom: 4,
center: new google.maps.LatLng(62.05350309096103, 15.373047874999997),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
);
infoBubble = new InfoBubble({
disableAutoPan: true
});
// Add an eventlistener to the map.
google.maps.event.addListener
(
map,
'click',
function(ev)
{
addMarker(ev);
}
);
}
function addMarker(ev)
{
// Get the distance.
var distance = getDistance( ev.latLng , treasureLocation );
// Skriv ut vart man klickade.
document.getElementById("click_info").innerHTML = "Du klickade " + distance + " ifrån skatten, försök igen!";
// Create a marker
var marker = new google.maps.Marker({
position: ev.latLng,
map: map,
clickable: true,
title: "Härifån är det bara " + distance + " till skatten!",
icon: "shovel.png"
});
// Hook the click on the created marker to show the created popup
google.maps.event.addListener
(
marker,
'click',
function(ev)
{
if( infoBubble != null ){infoBubble.close();}
infoBubble.setContent(marker.title);
infoBubble.setPosition(marker.position);
infoBubble.open(map, marker);
}
);
}
I can't really explain why but seems like infoBubble.setPosition(marker.position); is causing trouble. Just Delete it. You are using infoBubble.open(map, marker); to define bubble position, so you don't rly need it.
I am attempting to create a google map with markers on my page. I have an unordered list where each item has data attributes for latitude, longitude and title. Using JQuery I pull these values and produce a marker on the map for each item in the list. Everything seems to work OK except google maps will not load tiles as you pan around the map.
This is how I initialize the map:
var map;
// initialize google map
$(function () {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(CoordinatesLat, CoordinatesLong),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
}
// initiate map
map = new google.maps.Map($("#map")[0], myOptions);
// when map is loaded, add events and behaviors to it
google.maps.event.addListenerOnce(map, 'tilesloaded', addEventsToMap(".event")); //commenting this line prevents GMAP problems
});
FYI - before I was using maps.event.addListener() and the map would work momentarily and then become completely unresponsive. Changing it to maps.event.addListenerOnce() stopped the freezing but still has the tile loading problem.
And this is the callback, where evidently I've done something wrong:
//add events from event list to map. add behavior to events ie. mouseover
function addEventsToMap(selector) {
$(selector).each(function (i, $e) {
$e = $($e);
var latlng;
if ($e.attr("data-geo-lat") && $e.attr("data-geo-long")) {
latlng = new google.maps.LatLng($e.attr("data-geo-lat"), $e.attr("data-geo-long"));
$e.marker = new google.maps.Marker({
position: latlng,
map: map,
title: $e.attr("data-title")
});
google.maps.event.addListener($e.marker, 'click', function () { window.location = $e.attr("data-href"); });
google.maps.event.addListener($e.marker, 'mouseover', function () { $e.addClass("event-hover"); });
google.maps.event.addListener($e.marker, 'mouseout', function () { $e.removeClass("event-hover"); });
//when mouse hovers over item in list, center map on it's marker
$e.mouseenter(function () {
map.panTo(latlng);
});
}
});
}
Any idea what could be causing this?
I see a problem, though I'm not sure if it's the issue here. If you examine this line:
google.maps.event.addListenerOnce(map, 'tilesloaded', addEventsToMap(".event"));
What you are intending to do is call your 'addEventsToMap' once the map is loaded, but instead what you are doing is calling the function and then assigning the return value of that as a listener.
You need this instead, and I think it shouldn't crash anymore.
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
addEventsToMap(".event");
});
If that doesn't work, I would recommend looking at the Javascript Console of whatever browser you are using, to see what error is happening to make the map crash.