Jquery Map UI [ gmap() ], InfoBox and Handlebars

I may be asking a duplicate question here but none of the other questions have my exact circumstances...

I am using jQuery Map UI in order to output JSON replacing the default infoWindows with InfoBox in order to populate them with Handlebars.

Here is my code and below is my problem. I've tried to comment as much as I can.

    // instantiate some variables to hold the array of markers and 
    // the array of infoboxes
    var markers = [];
    var infoBoxes = [];

    // Instantiate a Handlebar template to create the content of the infoboxes
    var infoWindowTemplate = $('#infowindow-template').html();
    infoWindowTemplate = Handlebars.compile(infoWindowTemplate);

    $.each(json, function(i, m) {

        // add a marker ID to the JSON such that it can be returned and the
        // modified JSON be used to build a summary list with links to each 
        // of the markers
        json[i].marker_id = 'rig-marker-' + i;

        // create a new infoBox with content generated with Handlebars
        var infoBox = new InfoBox({
            content: infoWindowTemplate(m),
            alignBottom: true,
            disableAutoPan: false,
            maxWidth: 280,
            pixelOffset: new google.maps.Size(-140, -45),
            closeBoxURL: "img/close-btn.png",
            infoBoxClearance: new google.maps.Size(50, 50),
            enableEventPropagation: true
        });

        // add the infobox to the 'global' array
        infoBoxes.push(infoBox);

        // create the marker using the markerID from the modified json
        var marker = map.gmap('addMarker', {
            'position': new google.maps.LatLng(m.latitude, m.longitude),
            'bounds': true,
            'id': json[i].marker_id,
            'icon': 'img/spot-icon.png',
            'title': m.title
        })

        // add a click handler to the marker and assign the infoBox as the
        // content
        marker.click(function () {
            map.gmap('openInfoWindow', infoBoxes[i], this);
        });

        // add the current marker to the markers array in preparation 
        // for being passed to the marker clusterer.
        markers.push(marker[0]);
    });

So my problem is that each of the InfoBoxes contains the same content. It is always the content of the first marker that is opened giving the impression that the InfoBox is simply being moved to any subsequent clicked markers.

When I log the content of the InfoBox on a marker being clicked:

marker.click(function () {
    console.log(infoBoxes[i]);
    map.gmap('openInfoWindow', infoBoxes[i], this);
});

The console shows the appropriate content but that content does not match that of the InfoBox... Which is why I am so confused!

What am I missing about this? Is the problem with my understanding of jQuery Map UI or InfoBox?

Answers


OK, I have found out what I was doing wrong and so I'm answering my own question but I would still welcome any thoughts as to whether my solution can be improved...

Here it is refactored:

// instantiate an array for the markers
var markers = [];

// Instantiate a Handlebar template to create the content of the infoboxes
var infoWindowTemplate = $('#infowindow-template').html();
infoWindowTemplate = Handlebars.compile(infoWindowTemplate);

// get the map object from the canvas in order to 
var mapObject = map.gmap('get', 'map');

// create the infobox instance with all of the settings in place
// the content will be replaced on each click but the other seetings
// stay the same
var infoBox = new InfoBox({
    content: "<p>Empty</p>",
    alignBottom: true,
    disableAutoPan: false,
    maxWidth: 280,
    pixelOffset: new google.maps.Size(-140, -45),
    closeBoxURL: "img/close-btn.png",
    infoBoxClearance: new google.maps.Size(50, 50),
    enableEventPropagation: true
});

$.each(json, function(i, m) {

    // collect together the variables needed for adding the markers
    var latLng = new google.maps.LatLng(m.latitude, m.longitude);
    var id = 'rig-marker-' + i
    var title = m.title;
    var html = infoWindowTemplate(m);

    var marker = map.gmap('addMarker', {
        'position': latLng,
        'bounds': true,
        'id': id,
        'icon': 'img/spot-icon.png',
        'title': title
    }).click(function () {
        // overwrite the content of the infoBox
        infoBox.setContent(html);
        // open the infobox
        infoBox.open(mapObject, this);
    });

    // add a marker ID to the JSON such that it can be linked with
    // other site content
    json[i].marker_id = id;

    // add the current marker to the markers array in preparation 
    // for being passed to the marker clusterer.
    markers[i] = marker[0];
});

So InfoBox comes with a method setContent() which does exactly what it says.

There is only ever one instance of infobox and it is just reused rather than a new one being created for each marker... I suspect that there would be a performance improvement with lots of markers.

I'm still open to suggestions but this works for now...


Need Your Help

How to combine ls -v and convert commands in linux

linux ls

I want to convert files in a specific order. For conversion I am using this command:

Complex Number App - graphing with core-plot, power-plot or else?

ios graphics core-plot graphing

I'm coding iOS app that will explain complex numbers to the user. Complex numbers can be displayed in Cartesian coordinates and that's what I want to do; print one or more vectors on the screen.