Google map modal issue - javascript

I am trying to display google map into the Twitter bootstrap modal.
When user first click on the button Show map then he is able to see the map successfuly as i am generating the map onclick() function but when he closes the modal and reopen it then the map doesnot show properly and 90% part of the map goes grey like following
I even try this workaround that remove that whole div in which the map is bind and regenerate it but that trick doesnot work too kindly let me know how can i resolve my issue.
Following is my js function which i am calling onclick event of show map
function mapp()
{
//google.maps.event.trigger(map, "resize");
//$("#map_google_canvas").empty();
$("#map_google_canvas").remove();
$("#crmap").append("<div id='map_google_canvas'></div>")
var myOptions = {
center: new google.maps.LatLng(54, -2),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_google_canvas"), myOptions);
var addressArray = new Array("London, United Kingdom", "London Road, Brentwood, United Kingdom", "Brentwood, United Kingdom");
var geocoder = new google.maps.Geocoder();
var markerBounds = new google.maps.LatLngBounds();
for (var i = 0; i < addressArray.length; i++) {
geocoder.geocode({
'address': addressArray[i]
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
markerBounds.extend(results[0].geometry.location);
map.fitBounds(markerBounds);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
}
Kindly help,
Thanks

I am working with Angular, and what has just worked for me, on the ui.bootstrap.collapse AngularUI directive is to use a timeout. This directive has the same problem as the modals because the map size is not defined until the new view is fully load, and the map appears with grey zones. What I have done is to add this code to the button that opens the collapsed content. Maybe you can adapt it to your case with the button that opens the modal.
window.setTimeout(function () {
google.maps.event.trigger(map, 'resize')
}, 0);
Hope it helps.

I had the same issue. but I found an issue with modal shown event. as its not working with some version of issue so I just follow the bootstrap modal documentation to achieve it.
Bootstrap Modal Map Issue Solution :
$(document).ready(function(){
$('#locationMap').on('shown.bs.modal', function(){
google.maps.event.trigger(map, 'resize');
map.setCenter(new google.maps.LatLng(-33.8688, 151.2195));
});
});
Finally This works for me, It could help to someone.

If you are using bootstrap 3 you have to do this:
function showMap() {
var mapOptions = {
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
$('#mapmodal').on('shown.bs.modal', function () {
google.maps.event.trigger(map, 'resize');
map.setCenter(new google.maps.LatLng(54, -2));
});
$('#mapmodal').modal("show");
}
Also make sure that you did not set any max-width or max-height value to img - tags. If you did so in your css style sheet put this at the end of it:
#map img{
max-width:none;
max-height:none;
}
I am not quiete sure whether it is neccessary but setting a height value to the div holding your map should be a good thing:
<div id="map" style="height:400px"></div>
I assembled this from several stackoverflow discussions.

If you are using Angular, you should use $timeout instead of setTimeout.
Wrapping a function with a $timeout set to 0 will ensure that the wrapped function is executed after the current execution context is finished. In your situation Google Maps API will only repaint the map after modal and the element holding the map are fully rendered. You won't see any grey areas.
$timeout(function () {
google.maps.event.trigger(map, 'resize');
map.setCenter(new google.maps.LatLng(53.5085011, -6.2154598););
}, 0);

The visibility:hidden and visibility:visible could be used instead of display:none and display:block. This worked for me. You can even edit the CSS of the modal for this.

Since you are loading the map in a non-yet-defined width element you have this solution.
You should trigger a resize event on google.maps after initialize map with latlong
$('.modal').on('shown', function () {
// also redefine center
map.setCenter(new google.maps.LatLng(54, -2));
google.maps.event.trigger(map, 'resize');
})

I solved this issue thanks to user1012181 answer. I also personally like this pure CSS solution.
div#myModalMap.modal.fade.in{
visibility: visible;
}
div#myModalMap.modal.fade{
display: block;
visibility: hidden;
}

I also had this issue and came up with this easy solution.
Wait until your modal is completely loaded and then set the timeOut event on map function.
$('#MyModal').on('loaded.bs.modal',function(e){
setTimeOut(GoogleMap,500);
});
I am very sure It will work out in all cases.

I will use uiGmapIsReady wait the dom ready then force the map resize:
uiGmapIsReady.promise().then(function () {
var map = $scope.map.control.getGMap();
google.maps.event.trigger(map, 'resize');
});

well this is how the answers above helped but I had to call the main function using onclick .
<span data-target="#enlargeModal"data-toggle="modal" onclick="newMap()" class="fa fa-expand r"></span>
function newMap()
{
function showMap() {
//your map function
}
$('#enlargeModal').on('shown.bs.modal', function () {
var center = fullmap.getCenter();
google.maps.event.trigger(fullmap, 'resize');
fullmap.setCenter(center);
});
showMap();
}

Related

How to get onclick event of marker generated by getroute

In this jsfiddle is simplified version of my js: http://jsfiddle.net/Drecker/2m4kvxb8/4/ Note that interesting part of the jsfiddle is only showRoute method. And method showMarker only shows desired behavior on normal marker.
Basically I generate a route via gmap3 getroute with some waypoints. After clicking on a waypoint I need to open a small infobox with more custom information of that point - so basically somehow get onclick event of such waypoint (with some identification of that waypoint so I would be able to get proper information). I'm able to achieve desired behavior on a separate marker (as you can see in the jsfiddle - that's the fully functional separate marker on the top left), but not on the markers generated by directionrenderer.
Furthermore please note that my waypoints have stopover: false and such markers for some reason ignore (some) options like title, as you can see in jsfiddle.
Any help is very appreciated - I've tried several things none of them works.
Hope you are using the google APIs library some version, in case something like this
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places,geometry" type="text/javascript"></script>
You have one div space to show the map, say
<div id="map" style="width: 700px; height: 600px;"></div>
So you can use this for adding listener on markers
//location is an array variable where you store your co ordinates
//code to show map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(locations[0].latitude, locations[0].longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//adding listener
var marker,i;
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i].city);
infowindow.open(map, marker);
}
})(marker, i));
where
marker
is the varible which will be something like this,
//adding marker
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].latitude, locations[i].longitude),
map: map
});
Hope from above you got some idea, might be helpful for you with your problem
There is no such option, according to the documentation and a lot of similar questions here on the stackoverflow, you can't bind click action to waypoints.
I have a workaround for that problem. The main idea is to add markers instead of waypoints and change their icon. Marker has much more options than waypoint. So I removed waypoints and added markers. Note that you have to be much more precise when adding marker's location
options without waypoints:
options: {origin: {lat:49.9, lng: 14.9},
destination: {lat: 50.1, lng: 15.1},
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
added markers with a new icon and click event:
marker:{
values:[
{latLng:[49.96485, 14.88392], data:"Waypoint1", options:{icon: "http://mt.google.com/vt/icon/name=icons/spotlight/directions_transfer_icon_10px.png&scale=1"}},
{latLng:[49.97730, 14.88185], data:"Waypoint2", options:{icon: "http://mt.google.com/vt/icon/name=icons/spotlight/directions_transfer_icon_10px.png&scale=1"}}
],
options:{
draggable: false
},
events:{
click: function(marker, event, context){
var map = $(this).gmap3("get"),
infowindow = $(this).gmap3({get:{name:"infowindow"}});
if (infowindow){
infowindow.open(map, marker);
infowindow.setContent(context.data);
} else {
$(this).gmap3({
infowindow:{
anchor:marker,
options:{content: context.data}
}
});
}
}
}
}
Here is my workaround for that problem : DEMO

Javascript accordion feature causes partial displaying

I want to show 2 different maps in accordion(JavaScript Enabled). The main purpose of doing this was to show users an accordion so that users can click on one another to see rather than seeing two big <div> otherwise.
I have done this code (http://jsbin.com/ibanum/1/edit), but the problem is that the second map does appear partially not fully as map1. How to fix that issue?
OK here lies the answer. You should refresh the div on click. So here goes the final JavaScript. But before going there you may have a look at http://jsbin.com/ibanum/20/edit
$(document).ready(function () {
var fenway = new google.maps.LatLng(48.1391265, 11.580186300000037);
var mapOptions = {
zoom: 10,
center: fenway,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var map2 = new google.maps.Map(document.getElementById("map_canvas2"), mapOptions);
$('#accordion').accordion();
$('h3').click(function () {
google.maps.event.trigger(map, 'resize');
});
});
Now the line
google.maps.event.trigger(map, 'resize');
resizes the map as there is a click event on the <h3> tag. Hope this sample is clear
You have to refresh your map container when switching between accordion section by using :
google.maps.event.trigger(map, 'resize');
See the related topic : how-to-update-the-google-map-if-the-map-canvas-of-it-changed-its-dimenstions

jquery link toggle with google maps

Im having problems working out how to get this toggle working, by default it hides the map and when you click show map i want the map to slide down and change the link test to hide map which then of course will slide back up but does not seem to be working..... anyone got any ideas?
Also if anyone knows of a solution for the google maps issue im also having please let me know, because the made is hidden when you show / slides down it does not show most of the map (something about resizing i think i remember reading up on)
i have made a jsfiddle here: http://jsfiddle.net/DfVBb/ although does not work there at all for some reason. thanks in advance!
HTML
<div class="slideToggleBox">
<div id="map_div"> </div>
</div>
show map
JS
<script type="text/javascript">
$('#map_div').hide();
$('#slideToggle').click(function() {
$('#map_div').slideToggle('slow', function() {
$('#slideToggle').text('hide map');
}, function(){
$('#slideToggle').text('show map');
});
return false
});
</script>
Maps JS
$(document).ready(function() {
var latlng = new google.maps.LatLng(53.334583, -0.961674);
var options = {
zoom: 15, // This number can be set to define the initial zoom level of the map
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_div'), options);
var image = new google.maps.MarkerImage('/images/map-icon.png',
new google.maps.Size(680, 178),
new google.maps.Point(0,0),
new google.maps.Point(18, 50)
);
var marker1 = new google.maps.Marker({
position: new google.maps.LatLng(53.334583,-0.961674),
map: map,
icon: image
});
});
</script>
I managed to work out a solution for this and also fixing the resize issue
$(function () {
// create a center
var c = new google.maps.LatLng(53.334583, -0.961674);
//create map options object
var mapOptions = {
zoom: 14,
center: c,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
$("#slideToggle").click(function () {
$('#map_canvas').slideToggle(300, function(){
if ($('#slideToggle').text() !== "hide map") $('#slideToggle').text('hide map');
else $('#slideToggle').text('show map');
google.maps.event.trigger(map, "resize"); // resize map
map.setCenter(c); // set the center
}); // slide it down
});
});
I looked at your fiddle, it has to be cleaned. Based on my understanding, you're trying to toggle Google maps on button click.
Mistakes in your Fiddle:
(1) The Google maps is not initialized. The below is used to initialize Google maps.
google.maps.event.addDomListener(window, 'load', initialize);
(2) Your .slideToggle() has to be cleaned up. It has be somehow like
$('#slideToggle').on('click', function () {
$('#map_canvas').slideToggle('slow', function () {
if ($('#slideToggle').text() !== "hide map")
$('#slideToggle').text('hide map');
else
$('#slideToggle').text('show map');
});
return false;
});
I've created a JSFiddle, please go through it and share your thoughts.

Google map's marker not center after resize on bootstrap tab

I bought a geolocation map script and when applied to bootstrap tab it will only shown small top left span. I added resize to overcome it.
$(document).ready(function() { $(‘a[href=”#tab2”]’).click(function(e) { setTimeout(initialise, 1000); }); </script>
function initialise() {
var myMap = document.getElementById('map-myid1');
google.maps.event.trigger(myMap, 'resize');
};
});
The problem I am facing is the marker of map not center, it will hide left outside of map. How to fix it?
See in real action
In bootstrap 3.x.x, this script will help:
var map;
google.maps.visualRefresh = true; // Enable the visual refresh
function initialize() {
// map initialization code
}
google.maps.event.addDomListener(window, 'load', initialize);
$(function () {
$('a[href="#Location"]').on('shown.bs.tab', function(e) {
lastCenter=map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(lastCenter);
});
});
where a[href="#Location"] is the anchor selector of the tab.
I checked your page source and found that you're using setTimeout(initialise, 1000); Therefore it is bit slow to show map. Try replacing the below code.
$(document).ready(function() {
$('a[href="#tab2"]').click(function(e) {
initialise();
});
Try this:
var map = null;
var center = null;
var bounds = new google.maps.LatLngBounds();
function initMap()
{
map = new google.maps.Map(document.getElementById("Your div id"),
{
center: new google.maps.LatLng("mycenter"),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
center = bounds.getCenter();
map.fitBounds(bounds);
}
I had the same problem with Google Maps and Bootstrap Tab plugin.
I used the 'shown' event to initialize google map in tab instead of the 'click' event.
$('a[href="#tab2"]').on('shown',function(e) {
// Initialized once the google map
// ...
// ...
// use this to redraw google map when current tab is shown.
google.maps.event.trigger(document.getElementById('Your div id'), 'resize');
});

How to get some information in google maps without click event on marker and show this in a div, other than infoWindow

Hi I am showing some markers on my google map and on click of the marker, I am calling the click event and showing some info about that place to the right side(area other than Map and not as an infoWindow). Now this event gets fired on click, and by default when page loads my div remains blank, How can I have the div the basic information being shown up once the map loads up. I need to show the information that corresponds to the marker that is the center point of the map, and later when the users click the marker icons the info should change and correspond to the particular marker being clicked
I have tried something but it doesn't work:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var places = [];
places.push(new google.maps.LatLng(51.43581, -0.51744));
places.push(new google.maps.LatLng(48.87187, 2.31764));
places.push(new google.maps.LatLng(45.45979, 9.19681));
var infowindow;
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
}
}
$("document").ready(function () {
loadMap();
});
UPDATE EDITED
Basically I need something like Layer KML features
But the info should come on the right hand side by default for the first time. Later on when the marker is clicked, the info should change. I am also not adamant that I need this info in a kml file(xml is fine with me as well). I can just have a marker and info should popup on click and for the first time be default as well depending on the location of the user.
Bottom Line: I need the info to appear on click of a marker and by default when the page loads the info should appear corresponding to the center point of the map. which means users coming from different locations will see different info's corresponding to their location from where they are coming.(I am centering the map based on users location)
You can use the addDomListener event of the google maps api. Something like this:
<script>
function initialize() {
// Map initialization
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
<div id="map_canvas"></div>
</body>
Although the above code is Maps Javascript API code, the addDomListener() method binds to the window object of the browser and allows the API to communicate with objects outside of the API's normal domain.
further reading
Actually the basic Idea is that you need to read an XMl and parse the data and and show this in a seperate div on right side., This div you can create dynamically when you load the map e-g:
$("#body").append("<div class='newdiv'></div>")
From the google Docs in the section about InfoWindow:
Note that if you call open() without passing a marker, the InfoWindow
will use the position specified upon construction through the
InfoWindow options object.
So in your code, why don't you simply init your infoWindow and call the open() method? I am not particularly familiar with the api, but how about:
var infowindow = new google.maps.InfoWindow({
content: 'your initial text'
});
infowindow.open();
Or if you need the marker for special purposes on the infowindow, init an marker with the center position and use that in the infowindow.open(your_initial_pos) call.
You can use jQuery to .triger() a click event on the first marker on document.ready:
$(marker).trigger('click');
This will run the code you have already written and make it so when the page loads your div will be populated with data from whatever element you trigger the click on.
When you bind to document.ready you don't need encapsulate document in quotes:
$(document).ready(function () {...});
Or you could use the short-hand if you're into that sort of thing:
$(function () {...});
UPDATE
You can place the trigger function call after your for loop where you are setting up the markers:
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
//only run on the first marker
if (i === 0) {
//trigger a click event to show the first info-window
$(marker).trigger('click');
}
}
You can fire a tilesloaded event on the map object. Check out the Map reference for events
tilesloaded waits until the map tiles are actually loaded before firing. Using your code, you could do something like this:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
google.maps.event.addListener(map, 'tilesloaded', function() {
doSomething();
});

Categories