Empty
Empty

Reputation: 350

Google maps and knockoutjs

I am making a single page app where in the second view I need to display the Google map. I am using the Google maps API where the map object is to be created.

 var map = new google.maps.Map(mapId, {
        zoom: 5,
        center: new google.maps.LatLng(55, 11),
        mapTypeId: google.maps.MapTypeId.ROADMAP
 });

The parameter mapId is giving me a problem. The view contains a div with id say "mapId", but I am not able to get the id and so the map cannot be displayed. I tried HTML binding, attribute binding but it does not work. I am new to knockout. Please suggest some method

Upvotes: 8

Views: 11298

Answers (4)

Amulya Acharya
Amulya Acharya

Reputation: 751

I have modified "schmidlop" binding to reset marker on change in inputs (lat long inputs) and marker always in center of map.

Html

<input data-bind="value: mapOne().lat" />

<input data-bind="value: mapOne().lng" />

Binding , Include this in some js file and include it in html.

ko.bindingHandlers.map = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            $("#" + element.getAttribute("id")).data("mapObj","");
            mapObj = ko.utils.unwrapObservable(valueAccessor());
            var latLng = new google.maps.LatLng(
                ko.utils.unwrapObservable(mapObj.lat),
                ko.utils.unwrapObservable(mapObj.lng));
            var mapOptions = { center: latLng,
                              zoom: 12, 
                              mapTypeId: google.maps.MapTypeId.ROADMAP};

            mapObj.googleMap = new google.maps.Map(element, mapOptions);

            mapObj.marker = new google.maps.Marker({
                map: mapObj.googleMap,
                position: latLng,
               draggable: true
            });     

            mapObj.onChangedCoord = function(newValue) {
                var latLng = new google.maps.LatLng(
                    ko.utils.unwrapObservable(mapObj.lat),
                    ko.utils.unwrapObservable(mapObj.lng));

                mapObj.googleMap.setCenter(latLng);
                mapObj.marker.setPosition(latLng);                 
            };

            mapObj.onMarkerMoved = function(dragEnd) {
                var latLng = mapObj.marker.getPosition();
                mapObj.lat(latLng.lat());
                mapObj.lng(latLng.lng());
            };

            mapObj.lat.subscribe(mapObj.onChangedCoord);
            mapObj.lng.subscribe(mapObj.onChangedCoord);  

            google.maps.event.addListener(mapObj.marker, 'dragend', mapObj.onMarkerMoved);

            $("#" + element.getAttribute("id")).data("mapObj",mapObj);
        }
    };

View Model

self.mapOne = ko.observable();    


self.mapOne({'lat':ko.observable(87.22),'lng':ko.observable(27.22)});

Upvotes: 1

schmidlop
schmidlop

Reputation: 1406

You should use a custom binding like so:

ko.bindingHandlers.map = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var mapObj = ko.utils.unwrapObservable(valueAccessor());
        var latLng = new google.maps.LatLng(
            ko.utils.unwrapObservable(mapObj.lat),
            ko.utils.unwrapObservable(mapObj.lng));
        var mapOptions = { center: latLng,
                          zoom: 5, 
                          mapTypeId: google.maps.MapTypeId.ROADMAP};

        mapObj.googleMap = new google.maps.Map(element, mapOptions);
    }
};

Your HTML would look like this:

<div id="mapDiv" data-bind="style:{width:'300px',height:'300px'},map:myMap"></div>

Finally your view model:

function MyViewModel() {
    var self = this;
    self.myMap = ko.observable({
        lat: ko.observable(55),
        lng: ko.observable(11)});
}

Here is a fiddle that does a bit more than what you are asking but should work fine for your case as well.

Upvotes: 20

Gady
Gady

Reputation: 4995

Instead of mapId you'll want to use document.getElementById('map'), where 'map' is the id of the div containing the map (<div id="map"></div>). This jsFiddle should help.

Upvotes: 0

AlignedDev
AlignedDev

Reputation: 8232

Here's a good example of using Knockout JS and Google Maps. Hopefully, it will help get you on the right track. http://www.codeproject.com/Articles/387626/BikeInCity-2-KnockoutJS-JQuery-Google-Maps

Upvotes: 1

Related Questions