Search code examples
asp.net-mvcgoogle-maps-api-3centering

Google Maps and ASP .NET MVC - Center the map at a marker


I'm building a page with a Google MAP that has a side bar with dynamically created divs linked to positions of markers in the map.

I'm using ASP.NET MVC with JQuery and Google Maps API v3.

Here is a look of it.

MyPage

This page is loaded in a splash window and is generated dynamically.

In the background page the user types a state or city in an input field and in my controller action I search for all people that are located in that area and return a JSON. I get the JSON and populate the map with markers and then I make the list of divs in the side bar.

I'd like to add a function to those divs that when they are clicked the map will center at the marker.

I came up with an idea for this solution which I could not finish.

I added class="clickable" and the attributes "Lat" and "Lng" with the values equal to the ones in the markers they are related to, and I tried to get their click event with JQuery and then set the map center with its Lat and Lng like this:

$(".clickable div").click(function(){
    $('map_canvas').panTo($(this).attr('lat'), $(this).attr('lng'));
}    

I had 2 problems with this approach. - First, I didn't know how to get the map with JQuery. I found 2 ways using like $('map_canvas').gMap but it didn't work. Tried a couple more things that I've found here in Stackoverflow but also didn't work.

Second - The JQuery would not catch the event click from the DIVs. I tested on Google Chrome console the JQuery code and It worked but then my code would not trigger the click. I tried something like $(".clickable div").click(function(){ alert("test"); } on Google Chrome and it worked, but in my script it did not.

I also tried to add listeners using addDomListener in my code but couldn't get around that either.

Could anyone please give me a light what would be a good way to do this without having to recreate the map when a div is clicked.

I also don't like the idea of adding Lat and Lng attributes to the divs, I don't know if that would work in any browser or if its good practice. I'm just out of solutions to this.

Here is the code I'm using. (I removed some of it to make it shorter and easier to read)

$(document).ready(function () {

    //Google Maps API V3 - Prepares the ajaxForm options.
    var options = {
        beforeSubmit: showRequestPesquisaAdvogados,
        success: showResponsePesquisaAdvogados,
        type: 'post',
        resetForm: false
    };
    $('#form-pesquisaAdvogado').ajaxForm(options);

    //$(".clickable").click(function () { alert($(this).attr('lat')) });
});

function showRequestPesquisaAdvogados(formData, jqForm, options) {
    $("#modal-processing-background").show(); //Shows processing splash window
}

function showResponsePesquisaAdvogados(responseText, statusText, xhr, $form) {

    $("#modal-processing-background").hide(); 
    //Hide processing window

    loadSplashWindow();
    CreateMap(responseText);
    CreateSideBar(responseText);
    }
}

function CreateMap(json) {

    var mapOptions = {
        center: new google.maps.LatLng(json[0].Endereco.Lat, json[0].Endereco.Lng),
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP
        //  marker:true
    };

    var infoWindow = new google.maps.InfoWindow();

    var map = new google.maps.Map(document.getElementById("map-result"), mapOptions);

    for (i = 0; i < json.length; i++) {
        var data = json[i]
        var myLatlng = new google.maps.LatLng(data.Endereco.Lat, data.Endereco.Lng);
        var marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            title: data.Endereco.Logradouro
        });
        (function (marker, data) {                                
            // Attaching a click event to the current marker
            google.maps.event.addListener(marker, "click", function (e) {                    
                //  Prepare the infoWindows content. 
                var contentString = //my content; 
                infoWindow.setContent(contentString);
                infoWindow.open(map, marker);
            });

            //here I tried to add the listener to the div.
            google.maps.event.addDomListener($(".clickable")[i], 'click',
            function () {
                map.panTo(new google.maps.LatLng($(this).attr('lat'),
                     $(this).attr('lng')));
            });
        })(marker, data);
    }
}


function CreateSideBar(json) {
    $(".sideBarConteiner").empty();        

    for (i = 0; i < json.length; i++) {
        var contentString = 
            "<div class='clickable' lat='" + data.Endereco.Lat + 
            "' lng='" + data.Endereco.Lng + "' >" +
            //...div's content here
            "</div>";
        $(".sideBarConteiner").append(contentString);            
    }
}

If you have any suggestions to make the code better or better practices, since I have only 3 months of experience with programming I might be going in the wrong direction without knowing, so please, feel free to change something if you think it'd be a better way.

I know my post is a bit lenghty, I just wanted to make it clear.

Thank you for your support in advance.

Regards,

Cesar.


Solution

  • I've found a way to do this by creating a global variable in javascript and keeping the map information in order to call it again later. To to this I just added a var "map" right at the top of the .

    <script type="text/javascript">
        $.ajaxSetup({ cache: false }); //Forces IE to renew the cash for ajax.
        var zoom = 8;
        var mapOptions, map;    
    

    And then call a method to pan to the right point. I added the properties Lat and Lng to the div and then pass the div in the javascript function and get the attributes from it.

    function CreateSideBar(json) {
        $(".sideBarConteiner").empty();        
    
        for (i = 0; i < json.length; i++) {
            var contentString = 
                "<div class='clickable' data-lat='" + data.Endereco.Lat + 
                "' data-lng='" + data.Endereco.Lng + "' onclick='MarkerFocus(this)'>" +
                //...div's content here
                "</div>";
            $(".sideBarConteiner").append(contentString);            
        }
    }
    

    And in my function:

    function MarkerFocus(obj) {        
    var myLatlng = 
        new google.maps.LatLng($(obj).attr('data-lat'), $(obj).attr('data-lng')); 
    map.panTo(myLatlng);
    }
    

    It worked for me. I hope it helps you too.

    Thanks to all for the help and support.

    Cesar