Google Maps API v3, jQuery , Tabs, map not showing on hidden div - google-maps

This question had already been addressed multiple times, but all the solutions don't fix the problem in my case. It's as many already wrote: tabs used to display different parts of content, when loading the map in tab1 i.e. the one that opens on pageload, it displays fine.
When loading the map inside one of the other tabs, that need to be clicked, to be called, it doesn't draw the map as it is supposed to.
I already tried adding the google.maps.event.trigger(map, 'resize'); when the tab is clicked, but it doesn't do anything.
Here is my code, i am going crazy over this, have spent 10+ hours trying all suggestions !
This is the part that handles the tabs being clicked :
$(document).ready(function() {
//Default Action
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
//On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the rel attribute value to identify the active tab + content
if (activeTab=='#tab4') {
google.maps.event.trigger(map, 'resize');
map.setZoom( map.getZoom() );
}
$(activeTab).fadeIn(
); //Fade in the active content
return false;
});
});
When using an alert to see if the code is called on tab4 it works.
Here is the googlemaps code
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(<? echo $lattie; ?>, <? echo $langie; ?>),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
title: 'Click to zoom'
});
google.maps.event.addListener(map, 'center_changed', function() {
// 3 seconds after the center of the map has changed, pan back to the
// marker.
window.setTimeout(function() {
map.panTo(marker.getPosition());
}, 3000);
});
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
map.setCenter(marker.getPosition());
});
}
google.maps.event.addDomListener(window, 'load', initialize);
I am calling intitalize() in the body tag, changing this to the place where i am calling the resize, doesn't solve it either.
Finally the bit that shows the div with the map-canvas :
<li id="four">
<div id="map-canvas" style="width:575px; height:500px;float:left;border:1px solid #d74c15;"></div>
</li>
As i said, i am going crazy over this, i just can't get it to work, any help would be much appreciated !

This is a little bit tricky in one of my projects some time ago I got stuck on the same thing while trying to hide and show the map via a link.For me the resize event handler was all I needed but make sure to add the following code after it:
UPDATE here is the complete function used.
function showMap(){
if(animating == false)
{
animating = true;
if(mapVisible == false)
{
$("#map-wrapper").animate({
height:352
},500,function(){
$("#create-event-map").fadeIn("fast");
google.maps.event.trigger(eventsMap, 'resize');
var center = new google.maps.LatLng(38,24);
eventsMap.setCenter(center);
$("#show-map-wrapper a").html("Hide map");
mapVisible = true;
animating = false;
})
}
else
{
$("#create-event-map").fadeOut("fast",function(){
$("#map-wrapper").animate({
height:0
},500);
$("#show-map-wrapper a").html("Show map");
mapVisible = false;
animating = false;
})
}
}
return false;
}
working example here: http://goo.gl/2syX8
it's in the create.event.init.js file if you want to check it out
UPDATE
In your case if you want to refresh the map you should change this code:
if (activeTab=='#tab4') {
google.maps.event.trigger(map, 'resize');
map.setZoom( map.getZoom() );
}
$(activeTab).fadeIn(
); //Fade in the active content
With this:
if(activeTab == 'YOUR TAB ID')
{
$(activeTab).fadeIn(function(){
google.maps.event.trigger(map, 'resize');
var center = new google.maps.LatLng(<LAT>,<LNG>);
map.setCenter(center);
map.setZoom( map.getZoom() );
})
}
Store the last used lat and lng and replace them in this piece of code.

Related

Disable event click on Google Map v3

I add custom Google Maps Info Window for my GMap v3
How to disable 'click' event when i click on InfoWindow content and InfoWindow close button ?
Example code i puts on https://codepen.io/anon/pen/rwLdxG
function InfoBox(opts) {
google.maps.OverlayView.call(this);
this.latlng_ = opts.latlng;
this.map_ = opts.map;
this.content = opts.content;
this.offsetVertical_ = -195;
this.offsetHorizontal_ = 5;
this.height_ = 165;
this.width_ = 266;
var me = this;
this.boundsChangedListener_ =
google.maps.event.addListener(this.map_, "bounds_changed", function () {
return me.panMap.apply(me);
});
// Once the properties of this OverlayView are initialized, set its map so
// that we can display it. This will trigger calls to panes_changed and
// draw.
this.setMap(this.map_);
}
Here is a partial solution. Didn't want to spend time going through and learning about InfoBoxes - Infowindow would have been solved.
The following will remove the click event when you click/open a infoBOX. you need to find a way to re-add when closing the InfoBOX. InfoBox != Infowindow, I have no API to do it.
you need to add/change:
ADD: var listener to the top of script;
CHANGE:
google.maps.event.addListener(map, 'click', function(event) {
alert("google.maps.event.addListener");
});
to
listener = google.maps.event.addListener(map, 'click', function(event) {
alert("google.maps.event.addListener");
});
Change:
google.maps.event.addListener(markers[i], "click", function (e) {
var infoBox = new InfoBox({
latlng: this.getPosition(),
map: map,
content: this.content
});
google.maps.event.removeListener(listener)
});
To
google.maps.event.addListener(markers[i], "click", function (e) {
var infoBox = new InfoBox({
latlng: this.getPosition(),
map: map,
content: this.content
});
google.maps.event.removeListener(listener)
});
CODEPEN: https://codepen.io/anon/pen/rwLrYJ?editors=0010

How to set another function to closebutton in panorama

(sorry for my english) i have a problem,,, I´m trying to create a web in which user click on a polygon and it move user to another page with Google Street View Panorama (this i have). But i also need a code to move user back from "panorama page" to "polygons page" after clicking on close button in panorama. I tried to use the same code like i used before to move user to "panorama page" but it doesn´t work (it just closes panorama, but doesn´t move back to "polygons page"). The line:
google.maps.event.addListener(panorama, "closeclick", function(event) { window.location = "index.html"; })
is the code to move user back to "polygons page" (index.html). Here is the whole code:
function initialize() {
var panoOptions = {
pano: 'Kuchyn',
enableCloseButton: true,
pov: {
heading: 0,
pitch: 0,
zoom: 0
},
panoProvider: getCustomPanorama,
visible: true};
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('map-canvas'), panoOptions);
function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) {
return 'images/Untitled.jpg';}
function getCustomPanorama(pano, zoom, tileX, tiley) {
if (pano == 'Kuchyn') {
return {
location:
{pano: 'Kuchyn',
description: 'Kromeriz - Kuchyn'},
links: [],
copyright: 'Oznog (c) 2013',
Heading: 180,
tiles:
{tileSize: new google.maps.Size(4096, 2048),
worldSize: new google.maps.Size(4096, 2048),
centerHeading: 180,
verticalFOV: 90,
getTileUrl: getCustomPanoramaTileUrl}
};
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addListener(panorama, "closeclick", function(event) { window.location = "index.html"; })
Please help me, Jan.
Your eventListener for panorama is outside initialize function, move it under panorama declaration as follows:
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('map-canvas'), panoOptions);
// move it here
google.maps.event.addListener(panorama, "closeclick", function(event) { window.location = "index.html"; });
This is because you are not declaring panorama as a global variable, so it cant be attached correctly. Other option is to declare it as global variable var panorama; to above your initialize method.
Cheers.

How to tell if a Google Map Marker is currently selected?

I have a simple enough map on Google Maps V3.
I change the icon image on mouse over listener event, I change it back on mouse out simple enough.
I change the icon again when I click the marker, but, I want to keep that icon while the marker is selected. When I mouse out, the marker icon changes again because I told it to do so in the mouse out listener event.
I need to exclude the selected marker from the mouseout listener event but I can't figure out how to find the marker I have currently selected. Any ideas?
Here is my code
google.maps.event.addListener(marker, 'mouseover', function () {
this.setIcon("images/star-3-white.png");
});
google.maps.event.addListener(marker, 'mouseout', function () {
// this overwrites the image again,
// need to exclude the current one here
this.setIcon("images/star-3.png");
});
google.maps.event.addListener(marker, 'click', function () {
this.setIcon("images/star-3-white.png");
infowindow.setContent(this.html);
infowindow.open(map, this);
});
Either
create a member of the marker .selected and set that when you click on it, then test it in the mouseout function (and the mouseover function if you want to be complete), don't change the icon if it is set.
create a global variable (assuming there is only one marker selected at a time), set that equal to the marker that was clicked. In the mouseout (and mouseover) check if it is equal to the current marker (this), if it is don't change the icon.
A bit long winded but I just added a variable to store the current marker title which I know is unique. I then check to see if it is that one that I am selecting. Also, I make sure to reset all the markers so it doesnt stay the same color as a selected one:
var clickedMarkerTitle = null;
function addMarker(latLng, _title, contentString) {
marker = new google.maps.Marker({
map: map,
position: latLng,
icon: "images/star-3.png",
title: _title,
html: contentString
});
google.maps.event.addListener(marker, 'mouseover', function () {
this.setIcon("images/star-3-white.png");
});
google.maps.event.addListener(marker, 'mouseout', function () {
//this.setIcon("images/star-3.png");
testIcon(this);
});
google.maps.event.addListener(marker, 'click', function () {
resetMarkerIcons();
saveIconState(this);
this.setIcon("images/star-3-white.png");
infowindow.setContent(this.html);
infowindow.open(map, this);
});
markersArray.push(marker);
}
function resetMarkerIcons() {
// reset all the icons back to normal except the one you clicked
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setIcon("images/star-3.png");
}
}
function saveIconState(marker) {
clickedMarkerTitle = marker.title;
}
function testIcon(marker) {
$('#test').html('<span>' + marker.title + '</span>');
if (clickedMarkerTitle != null) {
$('#test').html('<span>' + marker.title + ' and its not null</span>');
if (marker.title != clickedMarkerTitle) {
$('#test').html('<span>' + marker.title + ' and ' + clickedMarkerTitle + '</span>');
marker.setIcon("images/star-3.png");
}
}
else {
marker.setIcon("images/star-3.png");
}
}
Stumbled on this answer when searching for something else. This will do.
var currentMarker = null;
var markerIcon = 'some.svg';
var markerIconHover = 'some-other.svg';
// Initialize marker here
[...]
// Set current marker on click
google.maps.event.addListener(marker, 'click', function() {
// Reset market icons
clearMarkerIcons();
// Set hovered map marker
marker.setIcon(markerIconHover);
// Set current marker
currentMarker = marker;
// Open infoWindow here
[...]
});
// Set correct icon on mouseover
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(markerIconHover);
});
// Set correct icon on mouseout
google.maps.event.addListener(marker, 'mouseout', function() {
if (currentMarker !== marker) {
marker.setIcon(markerIcon);
}
});
// Clear all set marker icons
function clearMarkerIcons() {
for (var i = 0; i < map.markers.length; i++) {
map.markers[i].setIcon(markerIcon);
}
}

street view panorama completely grey

I have created a street view backbone view. The problem is that when shown, the panorama is completely grey. I am not sure if it has to do with the fact that it is inside a tab and the panorama is rendered when the tab is opened.
I am guessing that it might be an analogous problem that is fixed calling the resize event. Is there any similar thing that I could do?
App.DetailStreetView = Backbone.View.extend({
initialize: function() {
this.latLng = new google.maps.LatLng(37.869085,-122.254775);
},
render: function() {
var sv = new google.maps.StreetViewService();
this.panorama = new google.maps.StreetViewPanorama(this.el);
sv.getPanoramaByLocation(this.latLng, 50, this.processSVData);
},
processSVData: function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
// calculate correct heading for POV
var heading = google.maps.geometry.spherical.computeHeading(data.location.latLng, this.latLng);
this.panorama.setPano(data.location.pano);
this.panorama.setPov({
heading: 270,
pitch:0,
zoom:1,
});
}
},
refresh: function() {
this.panorama.setVisible(true);
google.maps.event.trigger(this.panorama, 'resize');
}
});
EDIT:
I created a JSFiddle that replicates the problem: http://jsfiddle.net/kNS2L/3/
Yeah, this is the old display:none with Maps and Panoramas. It works when I add setVisible(true):
$('button').click(function() {
$('#pano').show();
panorama.setVisible(true);
});

Street view API 3 (add custom minimap) close button Street view and Pegman

In my script, when you drop the pegman on to the map, it loads Street View with a custom minimap. You can see the minimap with the pegman and move it for Street View, and it works fine.
However, when you click the close button on the street view, the minimap and Street View close fine but the pegman doesn't return to its default position. It stays on the map, and can't be re-dropped.
I want to move the pegman back to default position when Street View is closed, and if you drop it on map again to load Street View like the first time.
online code http://jsbin.com/ayejim/edit#preview
This is my function initialize:
function initialize() {
var lifestyle = [{}];
var myOptions = {
zoom: CITY_MAP_ZOOMING_FACT,
center: new google.maps.LatLng(CITY_MAP_CENTER_LAT, CITY_MAP_CENTER_LNG),
mapTypeId: google.maps.MapTypeId.<?php echo $maptype;?>
}
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
map.setOptions({styles: lifestyle});
/////////////////////////////
var g = google.maps;
var pano, mini;
var mapdiv = document.getElementById("map_canvas");
pano = map.getStreetView();
/** Listen to panorama's visibility changes to detect
* when pegman is dropped onto the map
* and when Street view is closed
*/
g.event.addListener(pano, "visible_changed", function() {
// Street view activated by dropping pegman
if (!mini && pano.getVisible()) {
// Container for mini map and close button
var c = document.createElement("div");
c.id = "minimap";
c.style.visibility = "visible";
var d = document.createElement("div");
d.id = "closebutton";
d.onclick = function() {
// Toggles button icon and moves copyright notice
var terms = document.getElementById("note");
// var terms = mapdiv.childNodes[1].childNodes[2];
if (c.style.visibility == "visible") {
c.style.visibility = "hidden";
d.className = "closed";
terms.style.marginRight = "24px";
}
else {
c.style.visibility = "visible";
d.className = "";
terms.style.marginRight = "170px";
}
};
c.appendChild(d);
mapdiv.appendChild(c);
mapdiv.appendChild(d);
mini = new g.Map(c, {
center: pano.getPosition(),
zoom: 15,
mapTypeId: "roadmap",
disableDefaultUI: true,
streetViewControl: true,
streetView: pano,
styles: lifestyle
});
/** Moves the 'Terms' notice to the left
* to ensure it's not covered up.
* There are two such notices in the document.
* Make sure to catch the right ones.
*/
g.event.addListener(mini, "tilesloaded", function() {
var terms = mini.getDiv().firstChild.childNodes[2];
terms.style.marginRight = "24px";
var sv_terms = mapdiv.childNodes[1].childNodes[2];
sv_terms.id = "note";
sv_terms.style.marginRight = "170px";
sv_terms.style.zIndex = "1";
});
// Binds mini map's center to pano position
mini.bindTo("center", pano, "position");
// Street view finished by click on Street view close button
} else if (mini instanceof g.Map && !pano.getVisible()) {
mapdiv.removeChild(document.getElementById("minimap"));
**//initialize(); if try call initialize again pegman back default position but map back to default position too like the first time.and markers hide , i don't know why this happens**
}
});
/////////////////////////
mgr = new MarkerManager( map );
google.maps.event.addListener(mgr, 'loaded', function() {
if (markers) {
for (var level in markers) {
google.maps.event.addDomListener( document.getElementById( level ), 'click', function() {
setCategoryVisiblity( this.id, this.checked );
});
for (var i = 0; i < markers[level].length; i++) {
var details = markers[level][i];
var image = new google.maps.MarkerImage(details.icons,new google.maps.Size(PIN_POINT_ICON_WIDTH, PIN_POINT_ICON_HEIGHT));
var myLatLng = new google.maps.LatLng(details.location[0], details.location[1]);
<?php if(get_current_city_set_zooming_opt() == '1') { ?>
multimarkerdata[i] = new google.maps.LatLng(details.location[0], details.location[1]);
<?php } ?>
markers[level][i] = new google.maps.Marker({
title: details.name,
position: myLatLng,
icon: image,
clickable: true,
draggable: false,
flat: true,
animation: google.maps.Animation.DROP
});
attachMessage(markers[level][i], details.message);
}
mgr.addMarkers( markers[level], 0 );
}
<?php if(get_current_city_set_zooming_opt() == '1') { ?>
var latlngbounds = new google.maps.LatLngBounds();
for ( var j = 0; j < multimarkerdata.length; j++ )
{
latlngbounds.extend( multimarkerdata[ j ] );
}
map.fitBounds( latlngbounds );
<?php } ?>
mgr.refresh();
}
});
// but that message is not within the marker's instance data
function attachMessage(marker, msg) {
var myEventListener = google.maps.event.addListener(marker, 'click', function() {
if (pano.getVisible()) {
infowindow.open(pano, marker);
} else {
infowindow = new google.maps.InfoWindow(
{ content: String(msg)
});
infowindow.open(map, marker);
}
if (infowindow) infowindow.close();
infowindow = new google.maps.InfoWindow(
{ content: String(msg)
});
infowindow.open(map,marker);
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
Not entirely sure why the current code is not working, but I'm also a little skeptic on the approach you're taking in the current code. Why not make a separate div for the panorama (streetview) and do some styling to the map_canvas div to replicate your current method (instead of using the minimap div). I've created a basis in this jsfiddle ( http://jsfiddle.net/svigna/FnrbX/embedded/result/ and http://jsfiddle.net/svigna/FnrbX/ for source code) that you can check out and possible use as a foundation for your solution.
Allow me to walk you through my code - with a little bit of looking into the streetView class properties and jquery I'm sure your question could be solved.
<body onload="initialize()">
<div id="container">
<div id="map_canvas" class="bigmap"></div>
<div id="pano" class="bigmap" style="display:none"></div>
</div>
first thing is first, in the mark-up we want to declare a div for the map and a div for the panorama, which will be bound to the map. We declare it in a container for styling purposes (when we want to overlap the map over the panorama). Notice the style of the panorama is initially set to display:none otherwise you'll be seeing a grayed out region (which is the pano without any location data because the pegman is not set).
#container {
width: 940px;
height: 640px;
position: relative;
}
#map_canvas,
#pano {
position: absolute;
top: 0;
left: 0;
}
#map_canvas {
z-index: 10;
}
.bigmap{
width:100%;
height:100%;
}
.minimap{
width:480px;
height:320px;
}
The styling here is essentially set to make it possible for the map_canvas div to overlap over the pano div when the pegman gets dropped. I used the concept from this solution for div overlapping ( How to overlay one div over another div). The .minimap and .bigmap classes make it easy to switch the map_canvas from one view to another, which will make more sense in the javascript section below.
function initialize() {
var fenway = new google.maps.LatLng(42.345573,-71.098326);
var panoramaOptions = {
enableCloseButton : true,
visible: false
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById("pano"), panoramaOptions);
var mapOptions = {
center: fenway,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetView : panorama
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
up to this point in the javascript we initialize all the map contents. it is pretty self explanatory, to look into the properties that are set in here have a look at the google maps api v3 reference - i found it to be very useful.
google.maps.event.addListener(panorama, "visible_changed", function() {
if (panorama.getVisible() && $("#pano").is(':visible')){
//moving the pegman around the map
}else if(panorama.getVisible() && $("#pano").is(':hidden')){
$("#pano").show();
$("#map_canvas").removeClass('bigmap');
$("#map_canvas").addClass('minimap');
}
google.maps.event.addListener(panorama, "closeclick", function() {
$("#pano").hide();
$("#map_canvas").removeClass('minimap');
$("#map_canvas").addClass('bigmap');
});
});
}
Note: the event listeners are still declared in the initialize() function. But essentially we listen for a change in the panorama visibility, but that alone is not enough to determine if there is actual data in the pano div element. Remember when we set the pano div display to none, well we can use jquery to check for the visibility. If it's visible, that means it is NOT the initial drop of the pegman - if it's hidden then that's where we change the class of the map_canvas to minimap. Also note that we listen for the closeclick in the "visible_changed" listener. This is because visible_changed also includes the closeclick action, so by putting it inside we're binding the listener to the other. Once the closeclick is triggered, we hide the pano div and change the map_canvas back to it's normal size.
The great thing about this approach is the native "closeclick" action on the streetView removes the pegman from the map it's set to and returns it back to normal (which is what you wanted in your problem). Also, to go back to your original position you can simply do a map.panTo() on the "closeclick" event listener to the initial location.
I hope this what you were looking for, if it's far off then my apologies! I know it's essentially asking you to redesign your current code structure - but just thought this approach was much simpler and seems to do the same thing you want done.