angular-maps not showing window inside marker - angularjs

I'm trying my best to show a window when clicking on a marker in angular-google-maps. Pretty much what is done here http://angular-google-maps.org/demo.
This is the function which generates the markers - it's called from a rest service, and each marker object can be viewed in coordinates.json:
var generateMarkers = function(markers) {
angular.forEach(markers, function(marker) {
marker.onClick = function() {
console.log('on click - opening window');
marker.showWindow = true;
$scope.$apply();
}
marker.closeClick = function() {
console.log('close click - hiding window');
marker.showWindow = false;
$scope.$apply();
}
});
$scope.map.randomMarkers = markers;
};
This is the code which declares the marker (no controller nesting and one $scope ). The window will inherit the
<google-map center="map.center" zoom="map.zoom" draggable="true"
bounds="map.bounds" control="map.control">
<markers models="map.randomMarkers" coords="'self'"
icon="'icon'"
click="'onClick'">
<windows
show="'showWindow'"
coords="'self'"
closeClick="'closeClick'" ng-cloak="">
<div>
Window with additional information
</div>
</windows>
</markers>
</google-map>
This is either a bug in angular-google-maps or I'm doing something wrong (which is likely)
I've created a plunkr, which demonstrates the behavior --> http://plnkr.co/edit/z1TdYlYbhSYWZb7n3L4M?p=preview
Please tell me what you think.

For posterity sake, this was answered over at https://github.com/nlaplante/angular-google-maps/issues/497 .
Basically, initialize to an empty array the property that coords is bound to, so that the reference gets updated correctly in angular.
This can be seen working here http://plnkr.co/edit/nbX0BIxNhxFrpzpruRWb?p=preview.

Related

How can I use a $watch() function in angularjs for Google Map API click event?

I want to catch the click event that happens when you click on a marker on a google map, and then execute some code. I've tried this, but it doesn't seem to be working.
$scope.$watch('click', function(newVal, oldVal) {
alert("Marker was clicked");
});
Any ideas?
Google maps displays the map in an iframe, and you can't capture clicks like that with an iframe. I use NgMap for map displays in my angularJS app, and the HTML structure ends up looking like this:
<ng-map class='map' style="">
<marker id='{{locale.id}}' position="{{locale.position}}" ng-repeat="locale in locales" on-click="showInfoW(locale)"></marker>
<info-window id="foo-iw">
<!-- info window HTML stuff here -->
</info-window>
</ng-map>
See that on-click in there? That is where you can get the click and do something in your code.
My JS looks something like this:
$scope.showInfoW = function(e, locale) {
$scope.vm.locale = locale
$scope.map.showInfoWindow('foo-iw', locale.id);
}
NgMap.getMap().then(function(map) {
vm.map = map
var latlng, bounds = new google.maps.LatLngBounds();
for (var i in $scope.locales) { // your marker list here
latlng = new google.maps.LatLng($scope.locales[i].position[0], $scope.locales[i].position[1]);
bounds.extend(latlng) // your marker position, must be a LatLng instance
}
$timeout(function() {
google.maps.event.trigger(map, 'resize');
$scope.map.fitBounds(bounds);
$scope.map.setZoom(14)
}, 500)
})
Without trying to explain everything, you can see that (using the wonderful NgMap package) you can capture the click on the marker.

Usin addListener on Polygon to delete vertex with AngularJs NgMap

I'm trying to delete a single vertex on the polygon drawn on the map using AngularJs NgMap, but nothing happens. I know I need to bind a rightClick event on the polygon, but nothing is happening.
I know there is a guide on how to delete the vertex here, but I'm not able to fire the event to proced.
Here is my code so far:
html:
<ng-map center="[{{vm.googleMaps}}]" zoom="13" map-type-control="false" street-view-control="false">
<marker position="[{{vm.googleMaps}}]"></marker>
<shape name="polygon" paths="{{vm.paths}}" editable="true"
stroke-color="#cde"
stroke-opacity="0.8"
stroke-weight="2"
fill-color="#cde"
fill-opacity="0.4">
</shape>
</ng-map>
controller:
$scope.$on('mapInitialized', function(event, map) {
var polygon = new google.maps.Polygon({
paths: vm.polygonPath
});
google.maps.event.addListener(polygon, 'rightclick', function() {
console.log('RightClick')
});
});
When I left click on the Polygon vertex, nothing happens, but I'm able to fully edit the polygon.
What am I doing wrong?
In order to have the proper event without using mapInitialized, I had to set a custom listener inside the ng-map directive and pass the event from there as well.
After that, I was able to use the googleMaps functions without using google.maps.event.addListener.
This is the final code:
html
<ng-map center="[{{vm.googleMaps}}]" zoom="13" map-type-control="false" street-view-control="false">
<marker position="[{{vm.googleMaps}}]"></marker>
<shape name="polygon" paths="{{vm.paths}}" editable="true"
on-rightclick="vm.myFunction($event)" //This is where we get the event with the point reference
stroke-color="#cde"
stroke-opacity="0.8"
stroke-weight="2"
fill-color="#cde"
fill-opacity="0.4">
</shape>
</ng-map>
AngularJs
I don't need to use the code I used on the question, so we can remove it.
vm.myFunction = function(event) {
NgMap.getMap().then(function(evtMap) {
var path = evtMap.shapes[0].getPath();
return path.removeAt(event.vertex);
});
}
The only difference from the GoogleMaps example, is that this way is going to remove the point right away, without the little box.

ng-map: How can I get the Marker object when I click it?

I am using the pretty cool ng-map library for angular, and I want to know how to access the underlying Marker Object referenced by ng-map marker directive
So, I have this markup:
<div id="map-search" data-tap-disabled="true">
<map zoom="15" disable-default-u-i="true">
<marker ng-repeat=" pos in positions" position="{{pos.latitude}}, {{pos.longitude}}" id="{{pos.index}}" on-click="pinClicked()">
</marker>
</map>
</div>
I haven't found a straight-forward way of accessing the Google Maps Marker Object during a on-click event in this case; From the controller:
app.controller('MapSearchController', function($scope) {
$scope.$on('mapInitialized', function(event, map) {
$scope.map = map;
//Assume existence of an Array of markers
$scope.positions = generatePinPositionsArray();
});
$scope.pinClicked = function(event, marker) {
console.log('clicked pin!');
//HOW CAN I GET THE MARKER OBJECT (The one that was clicked) HERE?
console.log('the marker ->', marker); //prints undefined
};
});
Thanks in advance,
this is the answer to access the market object. It is the exactly the same as Google maps api, nothing is different. Again use this inside on-click function.
------ EDIT -----
There are so many examples in testapp directory, those are useful when you find usage of ng-map.
$scope.foo = function(event, arg1, arg2) {
alert('this is at '+ this.getPosition());
alert(arg1+arg2);
}
Example:
https://rawgit.com/allenhwkim/angularjs-google-maps/master/testapp/events.html
You need to create an array of markers ! That's (in my opinion) the only way. See here
UPDATE: Does something like this plunkr works for you?
The idea is to pass the marker on the event on-click="pinClicked(this)". And then you can catch it later on the controller: $scope.pinClicked = function(events, marker) {...}

Add custom marker icon to angular-google-maps when markers are from external JSON

I'm new to Angular (so probably am making some silly mistakes) and I'm trying to add some markers to a map instance with a custom image icon.
I understand that the best way to do this is to add this into the items as suggested by Fedaykin but is there a way to do this if you can't change the JSON file?
I was able to add the custom icon for a single marker, so I wondered if I could do the same for several markers using 'forEach', but although this shows all my markers it doesn't add the icon.
$scope.marker = Mapdata.query(function() {
var image = "https://maps.google.com/mapfiles/kml/shapes/info-i_maps.png";
$scope.$watch('data', function(data) {
angular.forEach($scope.marker, function(markerList, id, coords, icon) {
$scope.markerList = [{
id: data.id,
coords: {
latitude: data.latitude,
longitude: data.longitude
},
icon: image
}];
});
});
});
The html is just the usual angular-google-maps stuff
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true">
<ui-gmap-markers models="marker.boards" coords="'self'" fit="'true'" icon="markerList.icon" click="'onClick'"></ui-gmap-markers>
</ui-gmap-google-map>
I have a plunker here to put it all in context.
Thanks for any help or advice :)
Made a few changes:
index.html
icon="markerList.icon" --> icon="'icon'"
script.js
I didn't quite understand what you were trying to to with the $watch - I ended up just setting the image attribute of each marker when the data is initially fetched.
Mapdata.query(function() { --> Mapdata.query(function(data) {
$scope.$watch thing -->
angular.forEach(data.boards, function(board) {
board.icon = image;
});
Here's the updated plunker.

Embed Vimeo video using AngularJS directive

I have a partial HTML page in an AngularJS app that I'm trying to add a vimeo video to. This template has an image and play button that fades out on click to show the underlying iFrame. I also want this click trigger to play the video, so that someone doesn't have to press two play buttons.
The div in my partial page template where this is happening working version of site here:
<div id="container" >
<div id="dummy"></div>
<div id="element">
<iframe id="player" class="fade {{playerFade}}" ng-src="http://player.vimeo.com/video/{{person.video}}?api=1&player_id=player&wmode=opaque" frameborder="0" allowfullscreen></iframe>
<img id="person_photo" class="fade {{person_photoFade}}" ng-src="{{person.photo_small}}" ng-src-responsive="[ [ '(min-width: 720px)', '{{person.photo_medium}}' ], [ '(min-width: 960px)', '{{person.photo_large}}' ], [ '(min-width: 1200px)', '{{person.photo_extralarge}}' ] ]" />
<a id="playButton" ng-click="playing=true" class="fade {{playButtonFade}}" ><img src="img/furniture/play.png" class="img_play" alt="play button"/></a>
</div>
</div>
Now, I did get this to work once, but that was with a static, non-Angular web page. The code I used to interact with the Vimeo API is something I took from SO#8444240. They were trying to figure out preloading. Since I have so many videos, I'm not interested in that, I just used this code to get my button interacting with my video.
I tried putting this script into my index.html page, but since it is removed from Angular, it doesn't work at all. I think I need a directive. Here is the current script code I have:
<script>
//INIT Vimeo API
var vimeoPlayers = document.querySelectorAll('#player'),
player;
for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
player = vimeoPlayers[i];
$f(player).addEvent('ready', ready);
}
function addEvent(element, eventName, callback) {
if (element.addEventListener) {
element.addEventListener(eventName, callback, false);
} else {
element.attachEvent(eventName, callback, false);
}
}
function ready(player_id) {
// Keep a reference to Froogaloop for this player
var container = document.getElementById(player_id).parentNode.parentNode,
froogaloop = $f(player_id);
$('#playButton a').click(function(){
$('#person_photo').fadeOut('12000');
froogaloop.api('play');
return false;
});
}
</script>
I've got a directive that controls the playbutton to fade it out (thanks to wmluke on a previous question) but I don't know how to translate this javascript into a directive. Here is my controller, too.
function DetailCtrl($scope, $routeParams, $http) {
$http.get('person.json').success(function(data) {
angular.forEach(data, function(person) {
if (person.id == $routeParams.personId)
$scope.person = person;
});
});
$scope.playing = false;
// Update the *Fade scope attributes whenever the `playing` scope attribute changes
$scope.$watch('playing', function (playing) {
$scope.playerFade = playing ? 'in' : '';
$scope.person_photoFade = playing ? '' : 'in';
$scope.playButtonFade = playing ? '' : 'in';
});
I tried writing this directive as best I could, but I don't know how to handle the ready calls to Vimeo API. It seems like there is a better way to do it in Angular.

Resources