Trying to load a simple google map within an angular-ui modal. However no luck. The data get's passed in fine, but nothing works in terms of the map... Please help.
$modalInstance.opened.then(function() {
var mapOptions = {
center: new google.maps.LatLng(34.834442, -82.3686479),
zoom: 8
};
new google.maps.Map(document.getElementById("eventMap"), mapOptions);
});
Inside the modal html:
<div class="row clearfix">
<div class="col-md-5" id="eventMap" style="display: block; height: 150px;"></div>
</div>
I tried this in the regular page HTML and worked fine...
What am I missing?
Thank you in advance!
You can use angularjs-google-maps; an AngularJS directive for Google maps that is very flexible and powerful and easy to use. I've prepared a working demo for your case:
http://plnkr.co/edit/eEtaGH?p=preview
I hope this helps.
To remove the grayness, according to https://angular-ui.github.io/angular-google-maps/#!/faq:
If rendering starts before elements are full size, google maps calculates according to the smaller size. This is most commonly the case with a hidden element (eg, ng-show). To fix this, use "ng-if" instead, as this will wait to attach to the DOM until the condition is true, which should be after everything has rendered fully.
I've modified your plunker http://plnkr.co/edit/JetUBY?p=preview to remove the grayness.
Controller:
var ModalInstanceCtrl = function ($scope, $modalInstance, lat, lng) {
$scope.render = true;
// code here
}
Template:
<map ng-if="$parent.render" center="[{{$parent.lat}}, {{$parent.lng}}]" zoom-control="true" zoom="8"> </map>
You need to trigger 'resize' event. Follow these lines:
var map = new google.maps.Map(document.getElementById("eventMap"), mapOptions);
google.maps.event.trigger(map, 'resize', function () {
// your callback content
});
I too ran Into a similar situation, where I am loading a map in an angular modal instance. I too searched many places and did't get the correct simple solution for it.
So I gone deeper and found a simple solution for this issue.
The issue is that, the map is trying to get the div from the modal before it gets loaded, and the solution is:
In your controller take a $timeout angular parameter,
function MyController($scope,$cookies,$modal,$window,roomService,$timeout) {
**** after all your model code is defined ****
$modalInstance.opened.then(function() {
function initialize() {
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("eventMap"),
myOptions);
}
$timeout(function() {
initialize()
}, 1000);
});
*** use the time out to make the div load and then call the map ***
}
This time out made the map to load perfectly in the modal. A simple solution.
Related
I am trying to use the Google Maps API to display a map within an Angular site but it appears to not initialise correctly.
My html page uses bootstrap nav nav-tabs and I use an Angular controller to switch between them.
<ul class="nav navbar-nav">
<li ng-class="{ active:myCtrl.isSet('map') }">
<a href ng-click="myCtrl.setTab('map')">Show Map</a>
</li>
</ul>
With one of the tabs containing only the google map canvas element - set up using an angular directive
Module.directive('mapPage', function() {
return {
restrict: 'E',
template: '<div id="map-canvas"></div>'
};
});
Within my angular controller I set up a listener for the window 'load' event to initialise the map as follows:
google.maps.event.addDomListener(window, 'load', myCtrl.initMap);
myCtrl.initMap = function() {
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(55.937879, -3.241619),
};
myCtrl.map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(55.937879, -3.241619),
map: myCtrl.map
});
myCtrl.map.setCenter(new google.maps.LatLng(55.937879, -3.241619));
}
What I see on screen is the map element showing a grey area with the location marker not centered correctly (it's just off screen).
If I move the map-canvas div to the main section of my index.html page (rather than a sub page within the app) it loads correctly, so I know my Google API js code and html is correct. The map also shows if the page is resized.
It just doesn't work when used on a page that is not rendered immediately. I have tried searching for similar questions/answers but could not find this particular issue.
I have created a simple fiddle that demonstrates the issue.
http://jsfiddle.net/johntough/nc0u7h2c/5/
Any help appreciated!
The issue is, you are loading Map on window load whereas the container will appear on click. Google Map has behavior (never seen documented yet but I have observed it many time though) that if the container is hidden on load, it does not load map in there. I changed your "load" to "click" and its working. The only change is as below,
google.maps.event.addDomListener(window, 'click', myCtrl.initMap);
See fiddle and verify yourself. http://jsfiddle.net/anandgh/nc0u7h2c/6/
I've got a bootstrap website that is using google maps to display a location as the header image.
You can see the webpage here: http://www.tarmastersasphalt.com/contact.asp
The html code in the page is this:
<div id="map" class="map img-responsive">
</div>
.
The page pulls in these standard bootstrap functions in the footer:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="assets/plugins/gmap/gmap.js"></script>
.
and the page also calls in this function:
var ContactPage = function () {
return {
//Basic Map
initMap: function () {
var map;
$(document).ready(function(){
map = new GMaps({
div: '#map',
lat: 38.9721102,
lng: -94.1037494
});
var marker = map.addMarker({
lat: 38.9721102,
lng: -94.1037494,
title: 'Tar Masters.'
});
});
},
//Panorama Map
initPanorama: function () {
var panorama;
$(document).ready(function(){
panorama = GMaps.createPanorama({
el: '#panorama',
lat : 38.9721102,
lng : -94.1037494
});
});
}
};
}();
.
And then performs this function:
<script type="text/javascript">
jQuery(document).ready(function() {
ContactPage.initMap();
});
</script>
.
This all works fine. What I want to do is to have the google map actually appear more zoomed out when first displayed on the page. I think you can use something like this &z=nn or ,nnz in the link to accomplish this.
.
For example - if you use a browser and go directly to this URL:
https://www.google.com.au/maps/place/1426+State+Hwy+TT,+Bates+City,+MO+64011,+USA/#38.9555594,-94.1035777,17z/data=!3m1!4b1!4m2!3m1!1s0x87c11502459d838b:0xadf0c711b5a89c2a
you will see the map as it is displayed on my website. But if you go here:
https://www.google.com.au/maps/place/1426+State+Hwy+TT,+Bates+City,+MO+64011,+USA/#38.9734448,-94.1113454,13z/data=!4m2!3m1!1s0x87c11502459d838b:0xadf0c711b5a89c2a
you will see the map as I want it to appear on my website. Notice the use of ,17z in the first link, and ,13z in the second link. (BTW: I also noticed that it seemed to change the coordinate numbers.. not sure what that is all about.)
.
So my question is as follows: Is there any way to tell the gmap function that I want it to be more zoomed out upon first displaying (without having to manually zoom out once it has been displayed)?
I think I have read somewhere that you can add some invisible markers that will force google to zoom out more in order to display all markers in the visable area.. but I am not sure how to accomplish this either.
.
Note: Please view the website on a large screen to see what I am talking about. (I use a static image as the header image when the window size get's small, because the interactiveness of the map doesn't work well with smart phone displays.. you can't scroll past the header image as it takes up the whole viewport, and all you do is move the map around, not scroll down the page.)
.
Any help will be appreciated!
you must define the zoom in the options you pass to GMaps, e.g.:
map = new GMaps({
div: '#map',
lat: 38.9721102,
lng: -94.1037494,
zoom: 10
});
(The default-value is 15)
I want to display google maps in my page for every place (lieux).In my HTML page I have the function for the google maps.
<script>
function initialize(long,lat) {
var mapCanvas = document.getElementById('map_canvas');
var mapOptions = {
center: new google.maps.LatLng(long, lat),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(mapCanvas, mapOptions)
}
google.maps.event.addDomListener(window, 'load', initialize);
document.getElementById('map_canvas').style.display='block';
</script>
And I have the button to dispaly the map.
<div class="tab-pane" id="tab_b" ng-controller="LieuController as lieu">
<div class="list-group-item" ng-repeat="lieu in lieu.lieux ">
<button onclick="initialize({{lieu.x}},{{lieu.y}})">Click me</button>
<div id="map_canvas"></div>
</div>
So is it possible to call the function with the parameters like I did or is there another way?
There are several problems with your code. Technically it's possible to mix Angular and pure javascript DOM 0 events like you are trying. However..
1. If you already tried your own code, then you should have seen the error Angular throws in this case:
Interpolations for HTML DOM event attributes are disallowed.
This effectively prevents usage Angular scope data with out-of Angular world code. There is a workaround though you can take. You can render necessary data in some attributes and then use them. For example:
<button onclick="initialize(this.getAttribute('data-x'), this.getAttribute('data-y'))"
data-x="{{l.x}}" data-y="{{l.y}}">Click me</button>
2. Event if you fix above problem you will still have to address duplicated ids issue. Since your initialize function is supposed to render a map in separate containers per ngRepeat row, each with id map_canvas. And at the same time you library onload event, which calls initialize again.
google.maps.event.addDomListener(window, 'load', initialize);
3. That being said, you should not build an app with such an unsuccessful design. You should really work on understanding main AngularJS concepts and philosophy.
In your case you should probably make use of ng-click instead of onclick, define initialize in some sort of custom service, maybe write custom directive to handle each separate map rendering in proper containers.
I was following these simple instructions in official documentation: https://developers.google.com/maps/documentation/javascript/tutorial
Everything works fine when I open the site for the first time. Map shows normally. The problem is when I navigate to other parts of the site. After I return to the location where map should be, the map doesn't show.
Here is the basic structure:
<ul>
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "About", about_path %></li>
<li><%= link_to "Contact", contact_path %></li>
</ul>
Javascript inside "Contact":
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=xxx&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<h1>Contact</h1>
<p>
Address & phone number
</p>
<div id="map-canvas" style="width: 35em; height: 35em;"/>
So, if I open the site on "Home" page and then navigate to "Contact", there is no map. But if I refresh the "Contact" site, map appears. What could be a problem?
Thank you.
EDIT1:
I tried to put my code inside ready function:
$.getScript('https://maps.googleapis.com/maps/api/js?key=xxx&sensor=false');
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
But when I do it like that, code breaks at this line:
center: new google.maps.LatLng(-34.397, 150.644),
Are you using Rails 4 with turbolinks enabled? If so, the load event will not fire when you move from the Home page to the Contact page – but hitting refresh fully loads the whole page, so the load event does fire. This would be consistent with the behaviour you're describing.
Try adding this at the end of your script block, in addition to the 'load' line:
google.maps.event.addDomListener(window, 'page:load', initialize);
Just provide a delay to the function that initialize the google map and it would work just fine.
setTimeout(function() {
//code for initializing the google map
}, 1000);
Setting the timeout to six seconds worked for me. The bigger the map the longer it takes, so gauge your timeout based on your map size.
It's hard to tell what might be going wrong. When you say you navigate to other parts of the site, are they all contained in one HTML file? Or perhaps they are loaded in dynamically with AJAX? Try triggering a resize event on the map when it's not showing properly.
google.maps.event.trigger(map, 'resize');
Alternatively this can be called after when you "navigate" to somewhere where it should be but isn't showing.
The problem seems to be with your turbolinks, bind your all activities in one function and call that function on document.ready as well as at document.page:load event.
$(document).ready( PageSetupFunction );
$(document).on("page:load", PageSetupFunction );
Actually here document.ready will be called when you refresh the page. But page:load event will be called once you come to this page from another link.
I've fixed this triggering the code after page is loaded using jQuery
$(document).on("pageshow","#contact",function(){
initialize();
});
I am new to JS, and have found the answer to a previous question, which brought up a new question, which brought me here again.
I have a Reveal Modal that contains a Google Map API. When a button is clicked, the Reveal Modal pops up, and displays the Google Map. My problem is that only a third of the map is displaying. This is because a resize trigger needs to be implemented. My question is how do I implement the google.maps.event.trigger(map, 'resize')? Where do I place this little snippet of code?
Here is my test site. Click on the Google Map button to see the problem at hand.
http://simplicitdesignanddevelopment.com/Fannie%20E%20Zurb/foundation/contact_us.html#
The Reveal Model script:
<script type="text/javascript">
$(document).ready(function() {
$('#myModal1').click(function() {
$('#myModal').reveal();
});
});
</script>
My Google Map Script:
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(39.739318, -89.266507),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
</script>
The div which holds the Google Map:
<div id="myModal" class="reveal-modal large">
<h2>How to get here</h2>
<div id="map_canvas" style="width:600px; height:300px;"></div>
<a class="close-reveal-modal">×</a>
</div>
UPDATE 2018-05-22
With a new renderer release in version 3.32 of Maps JavaScript API the resize event is no longer a part of Map class.
The documentation states
When the map is resized, the map center is fixed
The full-screen control now preserves center.
There is no longer any need to trigger the resize event manually.
source: https://developers.google.com/maps/documentation/javascript/new-renderer
google.maps.event.trigger(map, "resize"); doesn't have any effect starting from version 3.32
There were actually a couple of problems with your source code.
The initialize() function is created, but never called
The $(document).ready should be called after jQuery us loaded
The map should be a global variable (like #Cristiano Fontes said) and not a var map
(Important) The click event is never called. You're trying to combine the two methods Reveal from Zurb provides to open a dialog (one with JS, one with only HTML). You need to use the only JS method.
You're using the wrong ID (#myModal1 is never located in the HTML).
And now: Download the solution (Please provide us with a download/JSFiddle next time, so we don't need to create this ourselves).
Hope it helped!
Just add it here
<script type="text/javascript">
$(document).ready(function() {
$('#myModal1').click(function() {
$('#myModal').reveal();
google.maps.event.trigger(map, 'resize');
});
});
</script>
BUT you need to put the map as a global variable, so lose the var here
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(39.739318, -89.266507),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
--> map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
</script>
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
google.maps.event.trigger(map, 'resize');
});
});
Didn't found how to leave a comment for the last answer, but +1 for Cristiano Fontes help! It worked. In my case:
<script type="text/javascript">
$('div.map-box').hide();
$('li.map').mouseover(function(){
$('div.map-box').show();
google.maps.event.trigger(map, 'resize');
});
</script>
As now, google.maps.event.trigger(map, 'resize') does nothing. Like we having mat-dialog containing google map in it and there is the same problem. I`ve found some ways you can handle it:
Init map with a timeout.
Change the size of the parent container after map inits and then change it back.
But as for me, all these ways are pretty bad and I`m looking for something better.