tony09uk
tony09uk

Reputation: 2991

Refreshing google maps markers and infoBubbles using ajax

I am using asp mvc along with jquery and google maps api to display and update locations on a map.

My aim:

  1. Use markers to point to a number of locations

  2. Provide a small amount of information on those location using info bubbles info bubble repo

  3. OnClick refresh markers and info bubbles

What I've achieved so far:

I am able to load the map, place the pointers and display the info bubbles. After a few hours of struggling I have also managed to refresh the markers when the ajax call is made.

My problem:

  1. After the first update the markers refresh correctly but the info bubbles remain (I cannot work out how to clear them)

  2. New bubbles are displayed along with the new markers BUT these bubbles do not hold any data

  3. After the second update all markers disappear, but all info bubbles remain

Initial load

initial load of page

After call 1 (rent button clicked)

after call 1

After call 2 (buy button clicked)

after call 2

somePartialView.cshtml

@Html.HiddenFor(m => m.LatLng, new { @id = "latLng" })
<div id="map" class="google-maps">
    <div id="map-canvas"></div>
</div>

Javascript

NB: While testing I am hard coding the lat and lng values in the viewModel so I know each time a call is made only four values will be returned, which Is why I have hard coded four string into the contentString array.

$(document).ready(function () {
var map;
var iterator = 0;
var markers = [];
var markerLatLng = [];

var contentString = [
    '<div class="infobox-inner"><a href="08_Properties_Single.html"><img src="assets/img/icon-1.png" alt=""/><span>Sarkkara Villa</span></a></div>',
    '<div class="infobox-inner"><a href="08_Properties_Single.html"><img src="assets/img/icon-2.png" alt=""/><span>Sarkkara Flat</span></div>',
    '<div class="infobox-inner"><a href="08_Properties_Single.html"><img src="assets/img/icon-3.png" alt=""/><span>Sarkkara Commercial</span></div>',
    '<div class="infobox-inner"><a href="08_Properties_Single.html"><img src="assets/img/icon-4.png" alt=""/><span>Sarkkara Appartment</span></a></div>'
];
var latlng = $("#latLng").val();
var aryOfLatLng = latlng.split(';');

loadMarkers(aryOfLatLng);

function loadMarkers(ary) {
    $.each(ary, function (index, value) {
        if (value !== "") {
            var values = value.split(',')
            var loc = new google.maps.LatLng(Number(values[0]), Number(values[1]));
            markerLatLng.push(loc);
        }
    })
}

function initialize() {
    map = new google.maps.Map(document.getElementById('map-canvas'), {
        scrollwheel: false,
        zoom: 12,
        center: new google.maps.LatLng(52.520816, 13.410186) //Berlin
    });
    setTimeout(function () {
        drop();
    }, 1000);

}

// animate markers
function drop() {
    for (var i = 0; i < markerLatLng.length; i++) {
        setTimeout(function () {
            addMarker();
        }, i * 400);
    }
}

function addMarker() {
    var marker = new google.maps.Marker({
        position: markerLatLng[iterator],
        map: map,
        icon: 'assets/img/marker.png',
        draggable: false
        //,animation: google.maps.Animation.DROP
    });
    markers.push(marker);

    var infoBubble = new InfoBubble({
        map: map,
        content: contentString[iterator],
        position: markerLatLng[iterator],
        disableAutoPan: true,
        hideCloseButton: true,
        shadowStyle: 0,
        padding: 0,
        borderRadius: 3,
        borderWidth: 1,
        borderColor: '#74d2b2',
        backgroundColor: '#ffffff',
        backgroundClassName: 'infobox-bg',
        minHeight: 35,
        maxHeight: 230,
        minWidth: 200,
        maxWidth: 300,
        arrowSize: 5,
        arrowPosition: 50,
        arrowStyle: 0
    });

    setTimeout(function () {
        infoBubble.open(map, marker);
    }, 200);

    google.maps.event.addListener(marker, 'click', function () {
        if (!infoBubble.isOpen()) {
            infoBubble.open(map, marker);
        }
        else {
            infoBubble.close(map, marker);
        }
    });

    iterator++;
}

google.maps.event.addDomListener(window, 'load', initialize);

$("#rent").click(function () {
    ajaxRequest("/Map/_IsForSale", false)
})

$("#buy").click(function () {
    ajaxRequest("/Map/_IsForSale", true)
})

function ajaxRequest(targetUrl, data) {
    $.ajax({
        cache: false,
        url: targetUrl,
        type: "POST",
        data: { 'isForSale': data },
        success: function (data) {
            successCallBack(data);
        },
        error: function (request, status, error) {
            alert(error)
        }
    });
}

// Removes the markers from the map, but keeps them in the array. It will hide all markers.
function clearMarkers() {
    for (var i = 0; i < markers.length; i++) {
        markers[i].setMap(null);
    }
}

function successCallBack(data) {
    clearMarkers();
    var latlng = data.substring(data.indexOf("value=") + 7, data.indexOf(";\""));
    var ary = latlng.split(';');
    $.each(ary, function (index, value) {
        if (value !== "") {
            var values = value.split(',')
            var loc = new google.maps.LatLng(Number(values[0]), Number(values[1]));
            markerLatLng.push(loc);
        }
    })
    drop();
}
});

Upvotes: 1

Views: 1693

Answers (1)

Conan Tzou
Conan Tzou

Reputation: 174

1. After the first update the markers refresh correctly but the info bubbles remain (I cannot work out how to clear them)

Just like how you created a markers array to store your created markers to later clear with your #clearMarkers. I'd do similar for the infoBubbles, e.g. #clearInfoBubbles. Make an infoBubbles array to store info bubbles. According to the source code (see line 968) in the info bubble repo, you can close an info bubble with InfoBubble#close. Call your #clearInfoBubbles where necessary. In your #successCallBack perhaps.

2. New bubbles are displayed along with the new markers BUT these bubbles do not hold any data

You are creating infoBubble here like this

var infoBubble = new InfoBubble({
  map: map,
  content: contentString[iterator],
  ...
});

with contentString, which is only hardcoded to be 4 elements long.

By the time #initialize is finished, iterator will be equal to 4. The subsequent call to #addMarker (when the 1st rent button is clicked) will try to create an info bubble with contentString[4], however, that is undefined. iterator is never reset to 0.

3. After the second update all markers disappear, but all info bubbles remain

All info bubbles remain because they're never closed.

I'm not sure what your "buy" request is giving back to you. I'd check to see that the response is returning the data that you're expecting. My guess is that no new markers are getting created at this point.

Upvotes: 1

Related Questions