views:

2187

answers:

4

I'm trying to create a Google Map with multiple markers on it, that loads an alert when a marker is clicked.

var map = null;
function setupMap() { 

 map = new GMap2(document.getElementById("map")); 
 map.setUIToDefault();
 map.setCenter(new GLatLng( 0, 0 ), 1); 
 map.enableDoubleClickZoom(); 

 // Create the marker icon - will be repeated for each icon but
 // truncated for brevity in example
 var icon1 = new GIcon(G_DEFAULT_ICON);
 icon1.image = "uploads/1.jpg";
 icon1.shadow = "";
 icon1.iconSize = new GSize( 50, 50 );

 var latlng = new GLatLng( 0, 0 );
 markerOptions = { icon:icon1 };  
        marker1 = new GMarker( latlng, markerOptions );
 map.addOverlay( marker1 );
 GEvent.addListener( marker1, "click", loadInfo(1) ); 

} 

function loadInfo( a ) {
 alert( a );
}

window.onload = setupMap;

In the working example, I'll pass the marker object to loadInfo() and then load an InfoWindow, but for now, I'm just trying to get the action to happen when the marker is clicked. What's actually happening is that an alert box is loading (with the '1' in it, as expected) when the map loads. Multiple markers don't load multiple alert boxes, and after the initial alert box has loaded (which I don't want) clicking the markers doesn't do anything.

Any help is much appreciated, thanks!

+1  A: 

You're calling loadInfo in the .addListener, not providing a refernce to it.

GEvent.addListener( marker1, "click", loadInfo(1) );

try:

function wrap(method) {
    var args = Array.prototype.slice.apply(arguments,1);
    return function () {
         return method.apply(this,args);
    }
}


GEvent.addListener( marker1, "click", wrap(loadInfo,1) );

see http://www.alistapart.com/articles/getoutbindingsituations for more information on binding arguments to functions. also see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/apply for more information on the very useful apply() (also recommended you look at call() as well)

Jonathan Fingland
+4  A: 

In your addListener invocation, you're actually calling loadInfo instead of passing a reference to it. Try the following instead:

GEvent.addListener( marker1, "click", function() { 
  loadInfo(1); 
});

This will create an anonymous function which wraps your loadInfo method, calling the method when the anonymous function is executed.

Alternatively, if you weren't using any parameters in loadInfo, simply removing the parentheses would work too:

GEvent.addListener( marker1, "click", loadInfo);

Something worth keeping in mind when using such function references is the scope in which it will be called. If you were to use the 'this' reference, you'll run into the situation where 'this' within the callback function will in fact not refer to the scope in which it was created, but to the scope within which it's being executed which most likely will not contain the fields or methods you're expecting to call, resulting in errors stating Undefined instead. As Jonathan points out, you'll have to use the call() and apply() methods to bind explicitly to ensure your function executes within the correct scope.

Roshan
+1  A: 

loadInfo(1) means execute this function immediately, but you need to pass a callback function to the GEvent.addListener() method. For that, you can use anonymous function:

GEvent.addListener( marker1, "click", function() { loadInfo(1) });
esycat
A: 

Even though GEvent.addListener( marker1, "click", function() { loadInfo(1); }); was used, am not getting link to the marker to move next