Search code examples
arraysapigoogle-mapsmarkersinfobox

Array of Markers - Passing info held in array to InfoBox


I have an array of markers which are displaying fine. The problem I have is displaying an InfoBox for each using content held in the array. The array is called store_pins, elements 4 and 5 hold the values to be passed to the InfoBox (element 4 contains the filename of an image, 5 the caption for the image). The InfoBox code will

The InfoBox needs to be called when the Marker is clicked and should go at the bottom of my code where I have the comment // INFO BOX CODE GOES HERE.

My code in full is as follows:

    var map;
    var pop_up_info = "border: 0px solid black; background-color: #ffffff; padding:15px; margin-top: 8px; border-radius:10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; box-shadow: 1px 1px #888;";


    google.maps.event.addDomListener(window, 'load', initialize);
    
    function initialize() {
        var map_center  = new google.maps.LatLng(55.144178,-2.254122);
        var store_pins  = new Array();
        var pin_marker  = new Array();
        var pin_info    = new Array();
        var pin_infoop  = new Array();
        
        store_pins = [
            ['Bellingham Co-Op', 55.144178, -2.254122,'pin','bellinghamcoop.jpg','Staff at Bellingham Co-Op'],
            ['Leicester Tigers - Kingston Park', 55.018754, -1.672230,'rugby','kingparktigers.jpg','Stu with the Leicester Tigers Rugby Team'],
            ['The Hawick PSA Team', 55.421825, -2.797123,'rugby','hawickpsa.jpg','The Hawick PSA Team']
        ];

    var myOptions = {
        zoom: 3,
        minZoom: 3,
        center: map_center,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    
        map = new google.maps.Map(document.getElementById("trackingT-map"), myOptions);
    
        // Main Loop
        
        
        for(i=0;i<store_pins.length;i++)
        {
        var pos = new google.maps.LatLng(store_pins[i][1], store_pins[i][2]);
        var pinIcon = {
            url: 'icons/shirtpin.png',
            //The size image file.
            size: new google.maps.Size(50, 55),
            //The point on the image to measure the anchor from. 0, 0 is the top left.
            origin: new google.maps.Point(0, 0),
            //The x y coordinates of the anchor point on the marker. e.g. If your map marker was a drawing pin then the anchor would be the tip of the pin.
            anchor: new google.maps.Point(25, 20)
        };
        var pinShape = {
            coord: [0,0,50,55],
            type: 'rect'
        };

        pin_marker[i] = new google.maps.Marker(
        {
                position:       pos,
                map:            map,
                title:          store_pins[i][0],
                icon:           pinIcon,
                shape:          pinShape,
                zIndex:         107
           } 
        );
            
        pin_infoop[i] = {
                disableAutoPan: false,
                maxWidth: 0,
                pixelOffset: new google.maps.Size(-241, 0),
                zIndex: null,
                boxStyle: { 
                background: "url('infobox/pop_up_box_top_arrow.png') no-repeat",
                opacity: 1,
                width: "430px"
                },
                closeBoxMargin: "10px 2px 2px 2px",
                closeBoxURL: "icons/button_close.png",
                infoBoxClearance: new google.maps.Size(1, 1),
                isHidden: false,
                pane: "floatPane",
                enableEventPropagation: false,
                content:   store_pins[i][5]
        };

        pin_info[i] = new InfoBox(pin_infoop[i]);

            
            
        google.maps.event.addListener(pin_marker[i], 'click', function() {
            map.panTo(this.position);
            map.setZoom(10);
            pin_info[i].open(map, this);
        });
} 
};


Solution

  • I get a javascript error with your code:

    Uncaught TypeError: Cannot read property 'open' of undefined
    

    on this line:

    pin_info[i].open(map, this);
    

    i=3 and the highest available index of pin_info is 2.

    Your problem is the common issue of defining infowindows/boxes in a loop. Solved in this question with anonymous function closure:

    Change this:

        google.maps.event.addListener(pin_marker[i], 'click', function() {
            map.panTo(this.position);
            map.setZoom(10);
            pin_info[i].open(map, this);
        });
    

    To:

        google.maps.event.addListener(pin_marker[i], 'click', (function(marker, i) {
        return function() {
            map.panTo(this.position);
            map.setZoom(10);
            pin_info[i].open(map, this);
        }
      })(pin_marker[i], i));
    

    proof of concept fiddle (had to change the icons and some of the properties of the infobox so I could see what was going on as your code doesn't work as is)