Google map fitbounds not working with angularjs ng-dialog - angularjs

I am using ng-Dialog module of angularjs for vehicle trip view map. My angularjs directive for trip-map is working fine and map is loaded with fitbounds in the complete window (not in ng-dialog model popup) but it does not work in ng-dialog popup.
In ng-dialog, the googlemap is loaded but the map is not in fitbounds.
Earlier I thought that the issue was due to googe map fitbound not working fine, So I posted the below question. You can find more detail of my efforts here.
Google map fitBounds not working
ng-dialog call code in controller:
ngDialog.open({
template: 'Views/Main/tripdetail.html',
className: 'ngdialog-theme-plain',
controller: 'tripdetailController',
scope: $scope
});
Map fitbound code:
var marker;
var tripmap = mapService.getTripMap();
var bounds = new google.maps.LatLngBounds();
for (var j = 0; j < trips.length; j++) {
var ltlng = new google.maps.LatLng(trips[j].lat, trips[j].lng);
bounds.extend(ltlng);
// if (j == 0 || j == trips.length - 1) {
marker = new google.maps.Marker({
position: ltlng,
map: tripmap
});
// }
}
$scope.Bounds = bounds;
tripmap.fitBounds(bounds);
In window it look well as:
In ng-dialog modal popup, it moves to top left corner as:
Please advice me the solution. It will be appreciable.

It was due to map is resized by ngDialog popup directive.
Solved by call fitbounds in map resize callback with as
$scope.$apply(function () {
window.setTimeout(function () {
google.maps.event.trigger(tripmap, 'resize');
tripmap.fitBounds(bounds);
}, 100);
});
Thanks all for help.

Related

Display parsed data in info window in Google Maps

I am having trouble trying to display the event name from an array of objects in a parsed JSON file within Google Maps Ionic framework. Right now I have the markers displaying for each event with a simple string called "testing" which displays fine. The problem is I am unsure of how to display each events name within this info window and not the string I made. Any help would be appreciated. I'll post the sample image I have now as well as the info window functionality below. Thanks!
what I have displaying now:
here
marker/info window functionality:
getMarkers(){
//this.http.get('assets/data/markers.json').map((res)=>res.json()).subscribe(data=>{
this.http.get('http://app.toronto.ca/cc_sr_v1_app/data/edc_eventcal_APR?limit=500').map((res)=>res.json()).subscribe(data=>{
this.addMarkersMap(data);
});
}
addMarkersMap(markers){
for(let marker of markers)
{
var loc = marker.calEvent.locations[0]['coords'];
console.log(loc);
marker = new google.maps.Marker({
position: loc,
map: this.map,
});
var infoWindow = new google.maps.InfoWindow({
content: markers.eventName
});
google.maps.event.addListener(marker, 'click', function(str)
{
return function() {
infoWindow.setContent(str);
infoWindow.open(this.map, marker);
}
}(markers.eventName));
}
}
I correct myself. You could benefit from a closure here.
Use a self-calling function to seal your parameter to the infowindow:
google.maps.event.addListener(marker, 'click', function(str)
{
return function() {
infoWindow.setContent(str);
infoWindow.open(this.map, marker);
}
}(markers.calEvent.eventName));

How to open a Popup in Leaflet as Hover and not on Click

I want to open the popup in Angular Leaflet as a hover and not on click.
I have a markers array initialized and an overlay of a layer on top of the base layer.
I am trying to create a layer where buses and bus stops belong to each other. So each layer belongs to the same type in the overlays.
I am using the code
markers = [];
markers.push(
{ layer : layername,
lat : latitude,
lng : longitude,
message: busNames(data),
icon :{....}
}
});
I have another push marker set on the same layer which builds busStop data.
Now how do I display the popups when mouse is moved over them as hover instead of showing them on click
P.S - I am new to coding and hence please help me with proceeding further.
For each marker you are creating you have to listen to 'mouseover' and 'mouseout' events.
You open the popup when 'mouseover' is sent, close it when 'mouseout' is sent.
var marker = L.marker([51.5, -0.09]).addTo(map);
var tooltipPopup;
marker.on('mouseover', function(e) {
tooltipPopup = L.popup({ offset: L.point(0, -50)});
tooltipPopup.setContent("Hello");
tooltipPopup.setLatLng(e.target.getLatLng());
tooltipPopup.openOn(map);
});
marker.on('mouseout', function(e) {
map.closePopup(tooltipPopup);
});
Here is an example
First, you have to include 'leafletData' to your controller, after that add 'mouseover' and 'mouseout' events to your Marker.
angular
.module('myapp')
.controller("EventsController", [ '$scope', 'leafletData', function($scope, leafletData) {
$scope.$on('leafletDirectiveMarker.mouseover', function(event, args){
console.log('I am over!');
var popup = L.popup({ offset: L.point(0, -28)})
.setLatLng([args.model.lat, args.model.lng])
.setContent(args.model.message)
leafletData.getMap().then(function(map) {
popup.openOn(map);
});
});
$scope.$on('leafletDirectiveMarker.mouseout', function(event){
leafletData.getMap().then(function(map) {
map.closePopup();
});
});
}]);

ng-hide & ng-show in leaflet legend

I tried to create a leaflet legend using the 'ng-show' and 'ng-hide' attributes.
Unfortunately, the legend is not created on site load but on map load.
The attributes don't seem to work if they are added with javascript directly.
This code:
onAdd: function() {
var controlDiv = L.DomUtil.create('div', 'air-quality-legend');
controlDiv.setAttribute('ng-hide', 'true');
controlDiv.className = "airQualityIndex";
L.DomEvent
.addListener(controlDiv, 'click', L.DomEvent.stopPropagation)
.addListener(controlDiv, 'click', L.DomEvent.preventDefault);
var table = document.createElement('table');
var tr = document.createElement('table');
var td = document.createElement('table');
td.innerHTML = "test";
tr.appendChild(td);
table.appendChild(tr);
controlDiv.appendChild(table);
return controlDiv;
}
Produces that output.
As described there is a table when there should not.
Is there any way to add 'ng-hide' or 'ng-show' via javascript on runtime?
Thank you for your help in advance.
You'll need to compile the DOM of your custom control. To do that, you'll need to inject $compile into your controller, then after having added the control to your map use the getContainer method on your control instance and run $compile on it and attach it to the scope:
Control:
L.Control.Custom = L.Control.extend({
onAdd: function () {
var container = L.DomUtil.create('div', 'leaflet-control-custom')
header = L.DomUtil.create('h1', 'leaflet-control-custom-header', container);
header.textContent = 'NG-Hide test';
header.setAttribute('ng-hide', 'hide');
return container;
}
});
Controller:
angular.module('app').controller('controller', [
'$scope', 'leaflet', '$compile',
function ($scope, leaflet, $compile) {
$scope.hide = false;
leaflet.map.then(function (map) {
var control = new L.Control.Custom().addTo(map);
$compile(control.getContainer())($scope);
});
}
]);
Here's a working example on Plunker: http://plnkr.co/edit/xzRwTp9OZ8Zp8v7ktt2c?p=preview

Zoom Controller doesnt work Mapbox and Angular js

Im trying to work with Angular.js and Mapbox.
The map is loaded, from Mapbox with no problem. But the Zoom Control have problems, in the browser it shows the Zoom Control, but it doesnt appear in the Android Emulator. In the browser and in the emualtor, they dont work: they cant zoom in or zoom out.
I draw another Zoom Control and it happen the same problem, both in the browser appear and both doesnt Zoom in or Zoom out. In the browser they show both zoom control and Android Emulator both Zoom Controller doesnt appear and they doesnt work.
I have try this work Mapbox with no problem outside Angular:
https://www.mapbox.com/mapbox.js/example/v1.0.0/
Could some one could explain me or give me a hand.
thanks in advance
Here is the code that I was working:
.controller('loa', function($scope, $ionicModal) {
// MAPAS ------------------------------------------------------------>
$ionicModal.fromTemplateUrl('templates/calama.html', {
scope: $scope }).then(function(modal) {
$scope.modal1 = modal;
}, {
animation: 'slide-in-down',
focusFirstInput: true,
scope: $scope });
$scope.cierra1 = function() {
$scope.modal1.hide(); };
$scope.mapaCalama = function() {
$scope.modal1.show();
L.mapbox.accessToken = 'pk.xxxxxx';
var map = L.mapbox.map('map')
.setView([-22.4562, -68.9249], 6)
.addLayer(L.mapbox.tileLayer('itelius.xxxxx'));
L.mapbox.featureLayer('itelius.xxxxxx').on('ready', function(e) {
var clusterGroup = new L.MarkerClusterGroup();
e.target.eachLayer(function(layer) { clusterGroup.addLayer(layer); });
map.addLayer(clusterGroup);
}); };
I recentley put a zoom-slider object and works, but when I add a zoom control and try it I cant zoom in or zoom out.

AngularJS-ui toggle accordion depending on window width

I am looking to add the accordion functionality programatically when the browser is under a certain width. I thought I might just destroy the accordion when the $window watch reports a width under, say 400px, and re-initiate it again when not. But that seems to be a silly idea after searching for a couple hours. Is there a way to do this or a better way to archive the same result?
Ok so for everyone that might face a similar issue, this is what we ended up doing:
In the Angular config we added a dynamic router:
$routeProvider
.when('/:a', {
template: '<div data-ng-include="templateUrl">Loading...</div>',
controller: 'DynamicController'
})
Then the controller looks like this:
.controller('DynamicController', function ($scope, $rootScope, $routeParams) {
var mobile = false; //set desktop first as mobil has more logic
var maxWidth = 768; //adjust this value in media queries aswell!
var _isMobile = "";
//listen for changes on the scope var windowWidth
$rootScope.$watch('windowWidth',function(){
//check that we have not exceeded our max width
if($rootScope.windowWidth < maxWidth) {
_isMobile = "mobile"; //set the current view based on the width to mobile
}
else {
_isMobile = "desktop"; //set the current view based on the width to desktop
}
$scope.templateUrl = function() {
var temp = (_isMobile ? _isMobile : 'desktop');
return 'views/' + temp + '.html';
}(); //immediate gets called every time the windowWidth var changes passes in the current required view as a string.
});
})
Which has a watch set up for this directive:
angular.module('app.config',[])
.directive('resize', function ($window) {
return {
controller: function ($scope, $rootScope) {
$rootScope.windowWidth = $window.innerWidth;
angular.element($window).bind('resize', function () {
$rootScope.$apply(function () {
$rootScope.windowWidth = $window.innerWidth;
});
});
}
};
});
Now we got two views for mobile and desktop which both draw in the same content but wrap them into either an accordion or in another container.
That seems to work nicely and hope will help some other internet traveler.

Resources