Google map not showing on bootstrap modal - javascript

Im am planning to show a google map on a modal, but the map is not showing from the modal
This is my code:
<div style="margin-top:-7px;">
<button class="btn btn-default pull-right btn-mini " style="margin-right:5px;" data-toggle="modal" data-target="#myModal7"><i class="fa fa-globe"></i> Show Map</button>
</div>
<div class="modal inmodal fade" id="myModal7" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-md">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Address</h4>
</div>
<div class="modal-body">
<div class="panel mb25 mt5" style="width:500px; margin:0 auto; padding:10px;">
<div id="map" style="width: 500px; height: 500px;"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script type="text/javascript">
var address = 'Japan';
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16
});
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
google.maps.event.trigger(map, 'resize');
map.setCenter(results[0].geometry.location);
}
});
</script>
I did a research for this problem, ang i got the common answer, it is google.maps.event.trigger(map, "resize"); the problem is where will i put it, please help me.
Thanks

google map has problem with "display:none" parent.
initialize your map after showing modal for first time.
add a class for button or link that show modal.
$('.modal-opener-btn').one('click', function(){
//putt your code here
});
NOTICE : use "one" and dont use "on"
NOTICE : also can use modal "shown" listener, if this solution doesn't work
$('#myModal7').on('shown', function(){
//putt your code here
});
Just change bottom script tag and contents to :
<script type="text/javascript">
function init(){
var address = 'Japan';
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16
});
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
google.maps.event.trigger(map, 'resize');
map.setCenter(results[0].geometry.location);
}
});
}
$('#myModal7').on('shown.bs.modal', function(){
init();
});
</script>

regarding your research you can try to use that function
inside this
$(document).ready(function(){
$('#your_modal_id').on('shown.bs.modal',function(){
google.maps.event.trigger(map, "resize");
});
});

Had the same problem and this was the solution that made my day:
Make sure that you have jQuery on the initial page that called your modal page:

Related

Google Maps Search Box with autocomplete in Modal

Is it possible to have the Google Maps search box with autocomplete in a modal?
Not the whole map, just the search box.
Something like this:
Hours later seems that I found out a way to do it :)
HTML:
<div class="modal fade" id="searchModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-md" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="md-form ml-0 mr-0">
<!-- Autocomplete location search input -->
<div class="form-group">
<label>Τοποθεσία:</label>
<input type="text" class="form-control" id="search_input" placeholder="Αναζήτηση διεύθυνσης..." />
<input type="hidden" id="loc_lat" />
<input type="hidden" id="loc_long" />
</div>
<!-- Display latitude and longitude -->
<div class="latlong-view">
<p style="text-align: center;">
<b>Latitude:</b>
<span id="latitude_view"></span>
<b>| Longitude:</b>
<span id="longitude_view"></span>
</p>
</div>
</div>
<div class="text-center mt-4">
<button class="btn btn-cyan waves-effect waves-light" onclick="goTo()" style=" font-size: 1.2rem;">
<i class="fa fa-search ml-1"></i>
</button>
</div>
</div>
</div>
</div>
Javascript:
/* Google Maps Search handler */
var searchInput = 'search_input';
$(document).ready(function() {
var autocomplete;
autocomplete = new google.maps.places.Autocomplete((document.getElementById(searchInput)), {
types: ['geocode'],
componentRestrictions: {
country: "GR"
}
});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var near_place = autocomplete.getPlace();
document.getElementById('loc_lat').value = near_place.geometry.location.lat();
document.getElementById('loc_long').value = near_place.geometry.location.lng();
document.getElementById('latitude_view').innerHTML = near_place.geometry.location.lat();
document.getElementById('longitude_view').innerHTML = near_place.geometry.location.lng();
});
});
$(document).on('change', '#' + searchInput, function() {
document.getElementById('latitude_view').innerHTML = '';
document.getElementById('longitude_view').innerHTML = '';
});
/* Google Maps - Go to searched location */
function goTo() {
var lat = Number(document.getElementById("latitude_view").innerText);
var lon = Number(document.getElementById("longitude_view").innerText);
console.log(lat);
console.log(lon);
if (lat != 0 && lon != 0) {
map.setCenter({
lat: lat,
lng: lon
});
map.setZoom(18);
} else
alert("Μη αποδεκτές συντεταγμένες");
}
/* END of Google Maps Search handler */
Please note that you have to use the places library in order to make it work.
<script defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places&callback=initMap"></script>

HTML Javascript function only works on second click

I am trying to show a google map on a bootstrap tab, however the map only shows correctly when the tab is clicked on the second time. On the first click, there is a lot of grey area and the map needs to resize.
I've looked at this but nothing there helps.
js:
<script type="text/javascript">
$('a[href="#sectionB"]').on('shown', function (e) {
initMap();
});
function initMap() {
var uluru = {lat: -34.031342, lng: 18.577419};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: uluru,
mapTypeId: 'satellite'
});
var marker = new google.maps.Marker({
position: {lat: -34.031342, lng: 18.577419},
map: map
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MYKEYHERE&callback=initMap">
</script>
html:
<div class="col-md-12">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#sectionA">Details</a></li>
<li><a data-toggle="tab" id = "sectionb" href="#sectionB" onclick="initMap(); return false;">Location</a></li>
</ul>
<div class="tab-content">
<div id="sectionA" class="tab-pane fade in active">
<div class="col-md-8" style = "padding-top: 3%">
</div>
</div>
<div id="sectionB" class="tab-pane fade">
<div class="row">
<div class="col-md-8">
<div id ="map" style="width:400px;height:400px;">
</div>
</div>
</div>

Google Maps API multiple times on this page - Modal Bootstrap Return Json Success

The problem is when I open modal bootstrap which carries Google Maps.
Modal Bootstrap - _Edit.cshtml
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Editar</h4>
</div>
#using (Ajax.BeginForm("Edit", "Account", new AjaxOptions { HttpMethod = "POST", OnSuccess = "onModalSuccess" }, new { #id = "ModalformId", #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-xs-6">
#Html.LabelFor(m => m.GoogleMaps_Link)
#Html.TextBoxFor(m => m.GoogleMaps_Link, new { #id = "pac-input", #class = "controls", #readonly = true })
<br />
<div id="map-canvas" class="Help_GoogleMaps" style="width:865px;height:380px;" title="Edit"></div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-success" value="Save" />
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
#*Success Message Modal*#
<div id="ModalMsgBoxId" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">
<strong id="ModalTitleId" style="margin-left: 6px; font-size: 16px;"></strong>
</h4>
</div>
<div class="modal-body">
<p>
<div id="ModalContentId" style="margin-left: 6px; font-size: 16px;"></div>
</p>
</div>
<div class="modal-footer">
<button id="normalOkId" type="button" class="btn btn-success" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
}
// Google Maps Search
<script>
$(document).on("shown.bs.modal", function () {
if (window.google && window.google.maps) {
initAutocomplete();
return;
}
$script = $("<script>",
{
'type': 'text/javascript',
'src': 'https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&libraries=places&callback=initAutocomplete'
});
$script.appendTo($("head"));
});
function initAutocomplete() {
var LatLong = #Html.Raw(JsonConvert.SerializeObject(Model.Geo));
var LatLongSplit = LatLong.split(" ");
var lat = LatLongSplit[0];
var long = LatLongSplit[1];
//var Lat = (-23.5326148);
//var Long = (-46.803688);
var Endereco = #Html.Raw(JsonConvert.SerializeObject(Model.GoogleMaps_Link));
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(lat, long),
zoom: 11,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markerLatLong = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
map: map,
title: Endereco
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function () {
searchBox.setBounds(map.getBounds());
});
//Clear Markers
var markers = [];
// [START region_getplaces]
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function () {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
markerLatLong.setMap(null);
// Clear out the old markers.
markers.forEach(function (marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function (place) {
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
// [END region_getplaces]
}
var onModalSuccess = function(result)
{
if (result.EnableError)
{
// Clear.
$('#ModalTitleId').html("");
$('#ModalContentId').html("");
// Setting.
$('#ModalTitleId').append(result.ErrorTitle);
$('#ModalContentId').append(result.ErrorMsg);
// Show Modal.
$('#ModalMsgBoxId').modal(
{
backdrop: 'static',
keyboard: false
});
}
else if (result.EnableSuccess)
{
// Clear.
$('#ModalTitleId').html("");
$('#ModalContentId').html("");
// Setting.
$('#ModalTitleId').append(result.SuccessTitle);
$('#ModalContentId').append(result.SuccessMsg);
// Show Modal.
$('#ModalMsgBoxId').modal(
{
backdrop: 'static',
keyboard: false
});
// Resetting form.
$('#ModalformId').get(0).reset();
}
}
</script>
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditModel model)
{
if (ModelState.IsValid)
{
return this.Json(new { EnableSuccess = true, SuccessTitle = "Success", SuccessMsg = "Success" });
}
retur PartialView (_Edit, model);
}
The problem is in partial view. Just show a warning!
With the code below:
<div id="ModalMsgBoxId" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">
<strong id="ModalTitleId" style="margin-left: 6px; font-size: 16px;"></strong>
</h4>
</div>
<div class="modal-body">
<p>
<div id="ModalContentId" style="margin-left: 6px; font-size: 16px;"></div>
</p>
</div>
<div class="modal-footer">
<button id="normalOkId" type="button" class="btn btn-success" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
Picture:
The problem is modal Success, does it make Google Maps fail. How can I fix?
Thank you guys.
I solved the problem in another way. Using Bootstrap Alert.
Link: Alerts - Bootstrap
Remove code:
<div id="ModalMsgBoxId" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">
<strong id="ModalTitleId" style="margin-left: 6px; font-size: 16px;"></strong>
</h4>
</div>
<div class="modal-body">
<p>
<div id="ModalContentId" style="margin-left: 6px; font-size: 16px;"></div>
</p>
</div>
<div class="modal-footer">
<button id="normalOkId" type="button" class="btn btn-success" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
New code:
<center><div id="result"></div></center>
javascript:
$("#result").html('<div class="alert alert-success"><button type="button" class="close">×</button>Successfully updated record!</div>');
Now it works! I took example link: here

Angularjs - ng-map - Google Maps Javascript API v3 - how to Set best Zoom for Multiple markers

I'm using ngMap
in an angularjs app.
I'm displaying google-map with multiple markers onclick of Open map! button and first address present in the addresses array im taking as map center.
Here is The Plunk
example.js:
angular.module('plunker', ['ui.bootstrap', 'ngMap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.displayMap = function () {
$scope.addresses = [{ "address": "Hyderabad" },
{ "address": "Chennai" },
{ "address": "Bangalore" },
{ "address": "Kolkata" },];
$scope.latlng = [];
$scope.loop(0, $scope.addresses)
}
$scope.loop = function (id, addressesresult) {
if (id < addressesresult.length) {
var address = addressesresult[id].address;
geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$scope.latlng.push({
"lat": results[0].geometry.location.lat(),
"lng": results[0].geometry.location.lng(),
"title": results[0].formatted_address
});
if (id == ((addressesresult.length) - 1)) {
$scope.openPopup();
}
} else {
console.log('Geocode was not successful for the following reason:' + status);
}
id = id + 1;
$scope.loop(id, addressesresult);
});
}
}
$scope.openPopup = function () {
var modalInstance = $modal.open({
templateUrl: 'modal1',
controller: ModalInstanceCtrl,
scope: $scope,
resolve: {
lat: function () {
return $scope.latlng[0].lat;
},
lng: function () {
return $scope.latlng[0].lng;
},
latlng: function () {
return $scope.latlng;
}
}
});
};
};
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
var ModalInstanceCtrl = function ($scope, $modalInstance, lat, lng) {
$scope.lat = lat;
$scope.lng = lng;
$scope.render = true;
$scope.close = function () {
$modalInstance.close();
};
};
index.html:
<!doctype html>
<html ng-app="plunker">
<head>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
<script src="http://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.min.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<map ng-if="$parent.render" center="[{{$parent.lat}}, {{$parent.lng}}]" zoom-control="true" zoom="8"> </map>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="displayMap()">Open map!</button>
<script type="text/ng-template" id="modal1">
<div class="modal-header googlemodal-header">
<button type="button" ng-click="close()" style="opacity:1" class="close" data-dismiss="modal" aria-hidden="true"> <span style="color:red; ">x</span> </button>
<div align="center"><h3 class="modal-title">Addresses pointing in Google Map </h3></div>
</div>
<div class="modal-body">
<map ng-if="$parent.render" center="[{{lat}}, {{lng}}]" zoom="15" zoom-control="true" style="display:block; width:auto; height:auto;">
<marker ng-repeat="item in latlng"
position="{{item.lat}}, {{item.lng}}"
title="{{item.title}}"></marker>
</map>
</div>
<div class="modal-footer googlemodal-header">
<button class="btn btn-primary btn-sm" ng-click="close()">CLOSE</button>
</div>
</script>
</div>
</body>
</html>
All address related markers are displaying fine.
But how to set best zoom automatically for array of addresses, here these addresses i'm fetching from database, so these addresses changes for each request based on some condition.
ngMap recently(1.10.0) included a map attribute 'zoom-to-include-markers'. You can find an example here, https://rawgit.com/allenhwkim/angularjs-google-maps/master/testapp/map_zoom_to_include_markers.html
So the ideal zoom level depends on particular use cases. You can pick and choose the same accordingly. In depth explanations can be found in the documentation.
Although, I would suggest to have viewport biasing for zoomChanged events. The snippet shows how to implement it for angular (as suggested here).
This will ensure that the map is centered on the desired marker and you can fit all the markers in the panned area with it as well.
<div ng-controller="RectangleZoomCtrl" class="ng-scope">
<map zoom="11" center="33.6803003, -116.173894" map-type-id="TERRAIN" on-zoom_changed="zoomChanged()">
<shape name="rectangle" id="foo" stroke-color="#FF0000" stroke-opacity="0.8" stroke-weight="2" fill-color="#FF0000" fill-opacity="0.35">
</shape>
</map>
</div>

passing data to modal(bootstrap)

I have a multiple markers on google map and when i click them i need to open a modal window. The problem is every marker has a specific id and i need that id in each modal.
The modal html is:
<div class="modal fade" id="imageModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
The javascript code calling this function is :
function createMarker(pos, t, map) {
var marker = new google.maps.Marker({
position: pos,
map: map, // google.maps.Map
index: t
});
google.maps.event.addListener(marker, 'click', function() {
$('#imageModal').modal();
//alert("I am marker " + marker.index);
});
return marker;
}
So in imageModal i need to access the marker.index information which is dynamic. How can i do that? any ideas ?
Firstly I don't think index is a MarkerOption in Google Maps v3.
How I got this is, I used the title option in MarkerOption and it set to a dynamic string and then accessed it in the addListener event.
Here's how you can do it:
function createMarker(pos, t, map) {
var marker = new google.maps.Marker({
position: pos,
map: map, // google.maps.Map
title: t //where t must be a string
});
google.maps.event.addListener(marker, 'click', function() {
$('#imageModal').modal();
alert("I am marker " + this.getTitle() );
});
}
Hope this helps you!!

Categories