AngularJS ng-click not firing using angular-google-maps' windows - angularjs

I wanted to automatically center the map to the user's location once loaded so I used $scope.$apply() once geolocation is loaded as seen in my TestCtrl in controller.js here:
$scope.drawMap = function(position) {
$scope.$apply(function() {
$scope.myLocation.lng = position.coords.longitude;
$scope.myLocation.lat = position.coords.latitude;
$scope.map = {
center: {
latitude: $scope.myLocation.lat,
longitude: $scope.myLocation.lng
},
zoom: 14,
events: {
click: $scope.clickCallback
}
};
});
};
navigator.geolocation.getCurrentPosition($scope.drawMap);
$scope.test = function(){
alert("hola");
};
The $scope.clickCallback is used to push new markers to the map on click event.
// inside TestCtrl
var markers = [], counter = 1;
$scope.clickCallback = function(map, eventName, event){
var lat = event[0].latLng.lat();
var lng = event[0].latLng.lng();
markers.push(createNewMarker(counter, lat, lng));
$scope.$apply(function(){
$scope.newMarker = markers;
});
counter++;
};
As you can see, there's another $scope.$apply there to apply the new marker/s.
The createNewMarker() is where the markers (ui-gmap-markers) models is defined.
// still inside TestCtrl
var createNewMarker = function(i, lat, lng, idKey) {
if (idKey == null) {
idKey = "id";
}
var foo = "<h4>New Marker</h4><form><input type='text' placeholder='Event name' name='name'></input> <input type='button' value='submit'></input><input type='button' ng-click='test()' value='Delete marker'></input></form>";
var bar = $compile(foo)($scope);
var ret = {
latitude: lat,
longitude: lng,
show: true,
options: {
draggable: true,
animation: google.maps.Animation.DROP,
},
windows: {
title: "New Marker",
},
windowsOptions: {
content: foo,
}
};
ret[idKey] = i;
return ret;
};
Now the marker is showing fine when I click on the map including the window, but when I click on the Delete marker button, my $scope.test() function isn't firing up. I tried using $compile but it returns a bunch of error about $scope.
Here's my template:
<ion-content scroll="false">
<ui-gmap-google-map center='map.center' zoom='map.zoom' bounds="map.bounds" events="map.events">
<ui-gmap-markers models="newMarker" coords="'self'" icon="'icon'" options="'options'">
<ui-gmap-windows show="show" options="'windowsOptions'">
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</ion-content>
Anyone familiar with this scenario? I'm using Ionic Framework btw.

It does not have to be this complex.
As a creator of ngMap, I would recommend this,
http://ngmap.github.io/drawings.html#/marker-remove#marker-remove
To set the current location, just use current-location
<map center="current-location" zoom="12" on-click="addMarker()">
<marker ng-repeat="pos in positions" position="{{pos.lat}}, {{pos.lng}}"></marker>
</map>
http://plnkr.co/edit/e1SioHQ6NTSYCp0EbR0x?p=preview

Related

AngularJS change variable outside of function

I have a function in Angular that changes the center value for Google Maps when a user clicks on the map. The correct center value is then alerted to the screen but the marker does not change to that position like it should.
Web page: http://alainwebdesign.ca/pl2/#/getLocation
Controller:
.controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams",
function ($scope, $log, GoogleMapApi, $state, $stateParams) {
$log.currentLevel = $log.LEVELS.debug;
center = { latitude: 49.22, longitude: -122.66 }; //default center
alert(JSON.stringify(center));
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events:
{ click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
alert(JSON.stringify(center));
return center;
});
}
}
}
HTML partial/view:
<!--Add ability to input location as address-->
<div style="height: 100%">
<h1>TEST</h1> <!--NOT SHOWING ON PAGE WHICH MEANS THIS IS NOT BEING INVOKED WHEN
URL IS: '/getLocation' like it should-->
<ui-gmap-google-map
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-marker
idKey='1'
events='map.events'
coords='map.center'
>
</ui-gmap-marker>
</ui-gmap-google-map>
<script src='//maps.googleapis.com/maps/api/js?key=AIzaSyD4_0KuPivZyV-1EwNGmBCgLc_Z0o8Dyw8'></script>
</div>
You can directly set $scope.map.center instead of center variable and it will be ok. Here is working click function example:
click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
$scope.map.center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
});
}

angularjs googlemap not loading when trying to load in a modal

I am using AngularJS google maps to display map with markers.
The scenario is :
Initially Contact Details like Door no, Street, Area etc fields page will be displayed along with a static map. Once an edit button is clicked a pop-up with all the fields and map is displayed.
ex:
CODE:
html
<div class="row" ng-controller="userProfileController">
<ui-gmap-google-map center="center1" zoom="zoom1" pan="true" events="events">
<ui-gmap-markers models="models1" coords="'self'" options="'options'"></ui-gmap-markers>
</ui-gmap-google-map>
</div>
controller
$scope.center1 = {
latitude: lat,
longitude: lng
};
$scope.zoom1 = 8;
$scope.models1 = [{
id: 11445522,
latitude: lat,
longitude: lng,
options: {
title: "Current Location"
}
}];
Well everything works fine so far.
When edit is clicked i am trying to load another html in the modal that contains fields and a map. This time the map isn't loading. if I press 'F12' then map can be seen.
Code for popup:
html
<div class="col-sm-12">
<ui-gmap-google-map center="center3" zoom="zoom3" pan="true" events="events3" refresh="true">
<ui-gmap-markers doRebuildAll="true" doCluster="true" models="models3" coords="'self'" options="'options'"></ui-gmap-markers>
</ui-gmap-google-map>
controller
$scope.center3 = {latitude: 19.20742852680121,
longitude: 73.553466796875
};
$scope.zoom3 = 7;
$scope.models3 = [{
id: 5421222,
latitude: 19.20742852680121,
longitude: 73.553466796875,
options: {
title: "User Location"
}
}];
What might be the issue.? Can someone help me?
It displays like this:
I had a similar problem, but in my case, the user input an address and return the location. I found on the Internet the solution, and with some adjustments, I decided this way...
First, I create myController in app.js
app.controller('myController'), function ($scope) {
// my variable that's control my modal
$scope.showModal = false;
// my click event, like your 'Edit' button
$scope.createModal = function () {
$scope.showModal = true;
};
}
HTML index.html
<my-modal visible="showModal"></my-modal>
HTML modal.html
<div class="form-group">
<input type="text" class="form-control" ng-model="chosenPlace" details="chosenPlaceDetails" googleplace placeholder="Address"/>
<div class="map_container">
<div id="map_canvas" class="map_canvas"></div>
</div>
</div>
Then, in my modal.js, I created two Directive's
// Directive of Google Maps
angular.module('modal', [])
.directive('googleplace', function () {
return {
require: 'ngModel',
scope: {
ngModel: '=',
details: '=?'
},
controller: function ($scope) {
$scope.gPlace;
$scope.map;
$scope.marker;
$scope.initMap = function () {
// Set the initial lat and lng
var latlng = new google.maps.LatLng(-20.00, -47.00);
var options = {
zoom: 5,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map($("#map_canvas")[0], options);
$scope.marker = new google.maps.Marker({
map: $scope.map,
draggable: true,
});
$scope.marker.setPosition(latlng);
};
$scope.initMap();
},
link: function(scope, element, attrs, model) {
var options = {
types: ['geocode'],
componentRestrictions: { country: 'us' }
};
scope.gPlace = new google.maps.places.Autocomplete(element[0], options);
google.maps.event.addListener(scope.gPlace, 'place_changed', function() {
scope.$apply(function() {
google.maps.event.trigger(scope.map, 'resize');
var location = new google.maps.LatLng(scope.gPlace.getPlace().geometry.location.A, scope.gPlace.getPlace().geometry.location.F);
scope.marker.setPosition(location);
scope.map.setCenter(location);
scope.map.setZoom(16);
});
});
}
};
});
.directive('myModal', function () {
return {
templateUrl: 'modal.html',
restrict: 'E',
replace: true,
scope: true,
controller: function ($scope) {
},
link: function postLink(scope, element, attrs) {
scope.$watch(attrs.visible, function(value) {
if(value == true) {
$(element).modal('show');
}
else {
$(element).modal('hide');
}
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(event){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
When the user write his address, and hit Enter, the listener on the map, find the address and marker on the map.
I did like that because it was the best solution I found for my project.
I hope that helps.
PS: Sorry my english :/

Can't remove markers with AngularJS Google Maps plugin and Ionic

my html page renders the map by this:
<ui-gmap-google-map center='map.center' zoom='map.zoom'>
<ui-gmap-markers models="markers" coords="'coords'" icon="'icon'" ></ui-gmap-markers>
</ui-gmap-google-map>
And this is the controller:
angular.module('controllers.mapscontroller', [])
.controller("MapCtrl", function($scope, uiGmapGoogleMapApi, dataFactory) {
$scope.POIs=[];
$scope.markers = [];
uiGmapGoogleMapApi.then(function(maps) {
$scope.map = { center: { latitude: 40.3555013, longitude: 18.1573811 }, zoom: 8 };
navigator.geolocation.getCurrentPosition(function (position) {
$scope.map = { center: { latitude: position.coords.latitude, longitude: position.coords.longitude }, zoom: 8 };
});
dataFactory.getPOIs("it-IT")
.success(function (data) {
$scope.POIs=data.data.contents;
$scope.initializePOIsOnMap();
})
.error(function (error) {
console.log(error);
});
});
$scope.removePOIs = function() {
$scope.markers=[]; //<-- does nothing !!!
};
$scope.initializePOIsOnMap = function() {
for(var POI in $scope.POIs) {
var marker = {
id: $scope.POIs[POI].id,
coords: {
latitude: $scope.POIs[POI].latitude,
longitude: $scope.POIs[POI].longitude
},
options: { draggable: false , visible:true},
icon: "img/catIcons/"+$scope.POIs[POI].catid+".png"
};
$scope.markers.push(marker);
}
}
});
Maps gets displayed correctly, and markers as well.
But unfortunately, as you can read in $scope.removePOIs function, I can't remove the markers from the map. I've tried different solutions found over stackoverflow and the Web ($scope.markers.length=0, marker.setMap(null), ...) but no luck.
Any hint??
Thanks
Roberto
Solved!!
The problem was that I specified the controller twice: in the app.js and in the HTML page. The reason for specifying it in the HTML page is that I use the switchery plugin, which requires the ng-controller attribute to be set in the tag.
I removed the controller property from the app.js, putted all the HTML (the maps tags) within the tag and now it works.
Thanks!
Roberto
Here's an example of deleting markers using angularjs:
Example
Look at the script for remove markers example.

How do I add markers to a Google Map?

I am trying to have an input field that when submitted adds a marker to my Google Map. Right now when I submit the field it is creating the object but the marker is not being displayed. Right now I am able to get a location to show up if it is hard coded in but not when I add a new one. (I know that the view right now is only for the hard coded one, I have that so the current code is working)
Here is my code:
My View:
<form>
<input type="number" class="" ng-model="marker.markerLat" required="">
<input type="number" class="" ng-model="marker.markerLng" required="">
<button class="button" ng-click="addMarker(marker)">Add</button>
</form>
<google-map center="map.center" zoom="map.zoom">
<marker coords="marker.coords" options="marker.options" idkey="marker.id" >
</marker>
</google-map>
My Controller:
//Default location
$scope.map = {
center: {
latitude: 32.7833,
longitude: -79.9333
},
zoom: 11
}
$scope.options = {scrollwheel: true};
$scope.markers = [];
$scope.addMarker = function (marker) {
$scope.markers.push({
latitude: parseFloat($scope.markerLat),
longitude: parseFloat($scope.markerLng)
});
console.log('Maker add: ' + $scope.markers);
$scope.markerLat ="";
$scope.markerLng ="";
};
$scope.marker = {
id:0,
coords: {
latitude: 32.7833,
longitude: -79.9333
}
}
I would advice you to create a custom angular directive for your map.
But anyway, angular is not enough to get what you want working. You have to create google.maps objects. And set the map property of your marker to the map you have created.
Here is a little example :
.directive('map', function () {
return {
template: '<div></div>',
restrict: 'EA',
replace: true,
link: function (scope, element) {
scope.markers = [];
scope.map = new google.maps.Map(element[0], {
center: new google.maps.LatLng(32.7833, -79.9333),
zoom: 11
});
scope.addMarker = function (lat, lnt) {
var marker = new google.maps.Marker({
map: scope.map,
position: new google.maps.LatLng(lat, lng)
});
scope.markers.push(marker);
};
}
});
So you simply have to call the addMarker function with a lat and lng parameter. Use angular events to communicate between your controller and directive. More info about the methods here

angular-google-maps center zoom multiple markers

I'm using AngularJS for Google Maps and want to dynamically center and zoom a map based on multiple markers that are dynamically loaded. This is for a Cordova app using the Ionic Framework.
Here's my view:
<ion-view title="" ng-controller="MapCtrl as vm">
<ion-content class="padding">
<google-map id="mainMap" control="vm.googleMap" draggable="true" center="vm.map.center" zoom="vm.map.zoom" mark-click="false">
<markers idKey="mainMap" fit="vm.map.fit">
<marker idKey="marker.id" ng-repeat="marker in vm.map.markers" coords="marker.coords" options="marker.options">
<marker-label content="marker.name" anchor="2 0" class="marker-labels"/>
</marker>
</markers>
</google-map>
</ion-content>
</ion-view>
Here's my controller:
angular.module('myApp.controllers', [])
.controller('MapCtrl', function($scope, $ionicPlatform) {
var vm = this;
vm.googleMap = {}; // this is filled when google map is initialized, but it's too late
vm.mapMarkers = [];
vm.arrMarkers = [
{
id: "home",
name: "home",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
},
options: {
animation: google.maps.Animation.BOUNCE
}
},
{
id: "placeAId",
name: "Place A",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
}
},
{
id: "placeBId",
name: "Place B",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
}
}
];
vm.map = {
center: { //how to determine where to center???
latitude: xxxxxxx, //valid coords
longitude: xxxxxxx //valid coords
},
zoom: 12, //how to determine zoom dynamically???
fit: true,
markers: vm.arrMarkers
};
var setMapBounds = function () {
var bounds = new google.maps.LatLngBounds();
createMarkers();
var markers = vm.mapMarkers;
for(var i=0; i<markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
var map = vm.googleMap.control.getGMap();
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom()-1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom()> 15){
map.setZoom(15);
}
};
var createMarkers = function() {
var map = vm.googleMap.control.getGMap(); //vm.googleMap.control is undefined because this fire before map is initialized
angular.forEach(vm.restaurants, function(restaurant, index) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(restaurant.coords.latitude, restaurant.coords.longitude),
title: restaurant.name
});
vm.mapMarkers.push(marker);
});
};
$ionicPlatform.ready(function() {
setMapBounds();
});
})
So, my question is how do I center and zoom the map using multiple dynamically loaded markers? Also, how do I get an instance of googleMap.control (vm.googleMap.control) before the map is loaded?
Here's my code just in case anyone was wondering how to do this locally. This is a simple solution for what I needed and my indeed go back to angualr-google maps, but as of now this works fine in my application.
angular.module('myApp.controllers', [])
.controller('MapCtrl', function($scope) {
var vm = this;
vm.googleMap = null;
vm.mapMarkers = [];
var onSuccess = function(position) {
vm.userLocation.coords.latitude = position.coords.latitude;
vm.userLocation.coords.longitude = position.coords.longitude;
initializeMap();
};
var onError = function(error) {
alert('code: ' + error.code + '\n' + 'message: ' + error.message);
};
vm.userLocation = {
id: "home",
title: "home",
coords: {
latitude: 33.636727,
longitude: -83.920702
},
options: {
animation: google.maps.Animation.BOUNCE
}
};
vm.places = [
{
id: "78869C43-C694-40A5-97A0-5E709AA6CE51",
title: "Place A",
coords: {
latitude: 33.625296,
longitude: -83.976206
}
},
{
id: "52319278-83AA-46D4-ABA6-307EAF820E77",
title: "Place B",
coords: {
latitude: 33.576522,
longitude: -83.964981
}
}
];
var addMarkers = function() {
var userLocation = new google.maps.Marker({
map: vm.googleMap,
position: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude),
//animation: vm.userLocation.options.animation,
title: vm.userLocation.title
});
vm.mapMarkers.push(userLocation);
angular.forEach(vm.places, function(location, index) {
var marker = new google.maps.Marker({
map: vm.googleMap,
position: new google.maps.LatLng(location.coords.latitude, location.coords.longitude),
title: location.title
});
vm.mapMarkers.push(marker);
});
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < vm.mapMarkers.length; i++) {
bounds.extend(vm.mapMarkers[i].getPosition());
}
vm.googleMap.setCenter(bounds.getCenter());
vm.googleMap.fitBounds(bounds);
//remove one zoom level to ensure no marker is on the edge.
vm.googleMap.setZoom(vm.googleMap.getZoom() - 1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if (vm.googleMap.getZoom() > 15) {
vm.googleMap.setZoom(15);
}
};
var initializeMap = function() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 12,
center: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude)
};
var div = document.getElementById("map_canvas");
//var map = plugin.google.maps.Map.getMap(div, mapOptions);
vm.googleMap = new google.maps.Map(div, mapOptions);
addMarkers();
var width = screen.width;
var height = screen.height;
};
navigator.geolocation.getCurrentPosition(onSuccess, onError);
})
Your previous answer is good but doesn't include usage of the google maps directives you mentioned in the begining of the post. There is a way to do it using those directives, here is how:
Assuming we are in the directive's scope
Define scope.mapControl = {}; - this will have new access methods for map and markers
When defining your markup for the directives - for map and marker - include this control attribute to be added:
<ui-gmap-google-map center='map.center' zoom='map.zoom' control="mapControl">
<ui-gmap-marker ng-repeat="location in locations" coords="location.coordinates" options="location.markerOptions" idkey="location.id" control="mapControl">
<ui-gmap-window options="location.markerWindowOptions" closeclick="closeMarkerWindow(location.id)" show="true">
<div>{{location.description}}</div>
</ui-gmap-window>
</ui-gmap-marker>
</ui-gmap-google-map>
In your directive's event or some method:
var map = scope.mapControl.getGMap();
var markers = scope.mapControl.getGMarkers();
var bounds = map.getBounds();
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
map.setZoom(map.getZoom() - 1);

Resources