google maps close infoBox

Xtian picture Xtian · Feb 25, 2013 · Viewed 7.3k times · Source

I need to close an infoBox when another one is opened. I have seen alot of threads about this, and I have tried everything I've read and no luck.

I thought my issues was not having a global variable for infobox, but after I made one still no luck. But if you click on the Map it will close all the infobox's, so not sure why that works but not when you click on another marker?

Here is my current JS:

var infobox;

function createMap(mapDataTrending, mapDataRestaurants, mapDataBars) {
        //circles for 4sq Trending data
        var cityCircle, cityCircle2, cityCircle3, infobox, infobox2, infobox3;  

        for (var i = 0; i < mapDataTrending.length; i++) { 
            contentString = '<p class="venuename"> ' + mapDataTrending[i].name + '</p>';  
            contentString += '<p class="venueaddress"> ' + mapDataTrending[i].address;
            contentString += '<p class="venuecount"> ' + mapDataTrending[i].count + "  ARE HERE";

            infobox = new InfoBox({
                 content: contentString,
                 //content: document.getElementById("infobox"),
                 disableAutoPan: false,
                 maxWidth: 150,
                 pixelOffset: new google.maps.Size(-140, 6),
                 zIndex: null,
                 boxClass: "infoTrending",
                 boxStyle: {
                    width: "200px"
                },
                closeBoxMargin: "1px",
                closeBoxURL: "img/close-btn.png",
                infoBoxClearance: new google.maps.Size(1, 1)
            });

            var markerIcon = [
                            "img/marker-icon-1.png",
                            "img/marker-icon-2.png",
                            "img/marker-icon-3.png",
                            "img/marker-icon-4.png",
                            "img/marker-icon-5.png",
                            "img/marker-icon-6.png",
                            "img/marker-icon-7.png",
                            "img/marker-icon-8.png",
                            "img/marker-icon-9.png",
                            "img/marker-icon-10.png"
                        ];

        var image = new google.maps.MarkerImage(
            markerIcon[i],
            // This marker is 129 pixels wide by 42 pixels tall.
            new google.maps.Size(18, 18),
            // The origin for this image is 0,0.
            new google.maps.Point(0,0),
            // The anchor for this image is the base of the flagpole at 18,42.
            new google.maps.Point(9, 9)
        );



            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(mapDataTrending[i].lat, mapDataTrending[i].lng),
                anchor: new google.maps.Point(0,32),
                icon: image,
                map: map
            });         


            bindInfoW(marker, contentString, infobox);

        }

        function bindInfoW(marker, contentString, infobox){
            google.maps.event.addListener(marker, 'click', function() {

                if(infobox){
                    infobox.close();
                }

                infobox.setContent(contentString);
                infobox.open(map, marker);

                google.maps.event.addListener(map, 'click', function() {
                    if(infobox){
                        infobox.close();
                    }
                });

            });
        }

Answer

freejosh picture freejosh · Feb 25, 2013

Instead of instantiating multiple InfoBoxes in the mapDataTrending loop, instantiate one globally with an empty content. Then you can take out the local infobox variables, and the handlers will use the global reference.

Your script should end up like this:

var infobox = new InfoBox({
     content: '',
     disableAutoPan: false,
     maxWidth: 150,
     pixelOffset: new google.maps.Size(-140, 6),
     zIndex: null,
     boxClass: "infoTrending",
     boxStyle: {
        width: "200px"
    },
    closeBoxMargin: "1px",
    closeBoxURL: "img/close-btn.png",
    infoBoxClearance: new google.maps.Size(1, 1)
});

function createMap(mapDataTrending, mapDataRestaurants, mapDataBars) {
    //circles for 4sq Trending data
    var cityCircle, cityCircle2, cityCircle3;  

    for (var i = 0; i < mapDataTrending.length; i++) { 
        contentString = '<p class="venuename"> ' + mapDataTrending[i].name + '</p>';  
        contentString += '<p class="venueaddress"> ' + mapDataTrending[i].address;
        contentString += '<p class="venuecount"> ' + mapDataTrending[i].count + "  ARE HERE";

        var markerIcon = [
                        "img/marker-icon-1.png",
                        "img/marker-icon-2.png",
                        "img/marker-icon-3.png",
                        "img/marker-icon-4.png",
                        "img/marker-icon-5.png",
                        "img/marker-icon-6.png",
                        "img/marker-icon-7.png",
                        "img/marker-icon-8.png",
                        "img/marker-icon-9.png",
                        "img/marker-icon-10.png"
                    ];

    var image = new google.maps.MarkerImage(
        markerIcon[i],
        // This marker is 129 pixels wide by 42 pixels tall.
        new google.maps.Size(18, 18),
        // The origin for this image is 0,0.
        new google.maps.Point(0,0),
        // The anchor for this image is the base of the flagpole at 18,42.
        new google.maps.Point(9, 9)
    );


        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(mapDataTrending[i].lat, mapDataTrending[i].lng),
            anchor: new google.maps.Point(0,32),
            icon: image,
            map: map
        });         


        bindInfoW(marker, contentString);

    }

    function bindInfoW(marker, contentString){
        google.maps.event.addListener(marker, 'click', function() {

            if(infobox){
                infobox.close();
            }

            infobox.setContent(contentString);
            infobox.open(map, marker);

        });
    }

I also removed the second click handler that was getting bound on each click, since it's redundant and leaky if you don't have any markers that aren't bound with bindInfoW.