How to make an info window clickable? - google-maps-api-3

I have the below code, based on one of the API samples. A click on the map creates a marker. A click on the marker opens up an info window. Now I want a click on the info window to do something. E.g. a click anywhere might close it, as opposed to the little cross in the corner. Or a click on it might open a new URL. Etc.
Unfortunately it seems there is no "click" event for info windows.
The closest I've got is shown as a commented out line below: I wrap my info window content in a div, and give that an onClick. This works, but there is a big border around it. I really want to be able to click anywhere in the info window box.
Is there a way?
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Click Test</title>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
google.maps.visualRefresh = true; //New look visuals.
function initialize() {
var useragent = navigator.userAgent;
var mapdiv = document.getElementById("map-canvas");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdiv.style.width = '100%';
mapdiv.style.height = '100%';
} else {
mapdiv.style.width = '400px';
mapdiv.style.height = '600px';
}
var mapOptions = {
zoom:3,
center: new google.maps.LatLng(37.09024, -95.712891),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
function placeMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
var infowindow = new google.maps.InfoWindow({
//content: "<div onClick='test1()'>(lat,lng):<br/>"+location.lat()+","+location.lng()+"</div>"
content: "(lat,lng):<br/>"+location.lat()+","+location.lng()
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(marker.get('map'), marker);
infowindow.addListener('click',test1); //Does nothing
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
function test1(){alert("test1");}
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
UPDATE:
This image shows the problem when I use a clickable div inside the content (background set to red to show the extent of the region I can make clickable, and also that I can style; if I set a negative margin I just get scrollbars, not a bigger region!). It is the whole white area I want to be clickable, not just that red rectangle.

I decided to use InfoBox found in the Google Maps Utility Library. So in the header add a link to the library. Then replace the new google.maps.InfoWindow() line with this one:
var infowindow = new InfoBox({
closeBoxURL:"",
content: '<div onClick="test1();return false;" style="background:white;opacity:0.8;padding:8px">(lat,lng):<br/>'+
location.lat()+","+location.lng()+"</div>"
});
By setting closeBoxUrl to a blank string I get no close option. I added a large padding just so you can see that clicking right to the edge does indeed work.
You can also do it this way. I also use the boxClass option so the formatting is done in CSS:
var infoContent=document.createElement('div');
infoContent.innerHTML="(lat,lng):<br/>"+location.lat()+","+location.lng();
infoContent.onclick=test1;
var infowindow = new InfoBox({
closeBoxURL:"",
boxClass:"marker_popup",
content: infoContent,
});
(Aside, if doing it this way, on just some browsers it creates a marker below the InfoBox! Simplest fix is to change test1 so it looks like: function test1(event){alert("test1");event.preventDefault();return false;} )
P.S. I chose InfoBox over InfoBubble, as the latter has no documentation, and it had no obvious advantages to compensate for that major flaw! InfoBox has documentation and a reference. (links are for version 1.1.9)

Related

Find attached child objects of a-frame/ a-marker

I have a small A-frame based program to render text on a marker. When user click on the marker, I would like to scale the text, so it will be more visible. I can capture the click-event on the marker but how can I get it's child entities to scale?
My code can be found in https://codepen.io/asatrash/pen/rNLMgpa
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
</head>
<body>
<script>
//Multi Markers WebAR-AR.js and Aframe - Playing the Archive - Connected Environment CASA-UCL
//Global Variable
var markersURLArray=[];
var markersNameArray=[];
var allow_clicks = false;
AFRAME.registerComponent('markers_start',{
init:function(){
console.log('Add markers to the scene');
var sceneEl = document.querySelector('a-scene');
//list of the markers
for(var i=1; i<6; i++)`enter code here`
{
var url="https://raw.githubusercontent.com/asatrash/ARInWeb/main/resources/markers/pattern-Individual_Blocks-3.patt";
markersURLArray.push(url);
markersNameArray.push('Marker_'+i);
//console.log(url);
}
for(var k=0; k<5; k++)
{
var markerEl = document.createElement('a-marker');
markerEl.setAttribute('type','pattern');
markerEl.setAttribute('url',markersURLArray[k]);
markerEl.setAttribute('id',markersNameArray[k]);
markerEl.setAttribute('registerevents','');
sceneEl.appendChild(markerEl);
var boxEl = document.createElement('a-box');
boxEl.setAttribute('id','box');
boxEl.setAttribute('depth','0.001');
boxEl.setAttribute('width','6');
boxEl.setAttribute('height','4');
boxEl.setAttribute('opacity','0.25');
boxEl.setAttribute('position','0 -2 -4');
boxEl.setAttribute('rotation','0 0 0');
boxEl.setAttribute('material', {color: '#000000'});
markerEl.appendChild(boxEl);
var textEl = document.createElement('a-text');
textEl.setAttribute('id','text');
textEl.setAttribute('text',{color: '#ffff00', align: 'left', value:'This is a very log text /b \n line which might or might not wrap', width: '2' });
//textEl.setAttribute('position', '-1.4 1.5 0');
textEl.setAttribute('position', '-2.5 1.5 0')
textEl.setAttribute('scale', '2 2 0');
boxEl.appendChild(textEl);
}
}
});
//Detect marker found and lost
AFRAME.registerComponent('registerevents', {
init: function () {
const marker = this.el;
marker.addEventListener("markerFound", ()=> {
var markerId = marker.id;
console.log('Marker Found: ', markerId);
allow_clicks = true;
});
marker.addEventListener("markerLost",() =>{
var markerId = marker.id;
console.log('Marker Lost: ', markerId);
allow_clicks = false;
});
marker.addEventListener('click', (evt) => {
if (allow_clicks){
console.log("CLICKED!!!" + marker.id);
//I want to scale the box and the text attached to the marker jere
}
});
},
});
</script>
<a-scene markers_start vr-mode-ui="enabled: false" color-space="sRGB" renderer="gammaOutput: true"
embedded arjs='debugUIEnabled: false; sourceType: webcam; patternRatio: 0.85; trackingMethod: best;'>
<a-entity id='userCamera' camera look-controls >
<a-cursor> </a-cursor>
</a-entity>
</a-scene>
</body>
</html>
Did bit more testing and found out the following.
The 'click' event doesn't work as I expected on the marker. It is registered to the whole scene and it get invoked irrespective of the place I click. Which is not what I want. I am looking at using intersection Points to get it working.
However the getting access to the child can be easily done if you put unique ids. We can use the normal document.getElementById("boxelementId"); and change the attributes using the setAttribute method.
Ex: To change the text
var markerTextEl = document.getElementById(markerTextxId);
markerTextEl.setAttribute("value", "Current Temperature is: " + data);
I used above inside the 'markerFound' event to show different/current value when user point to a particular marker.

Google map in fullscreen with bootstrap modal

I have a google map. When I click a marker I show a bootstrap modal with style="z-index:999999999999999999999999999". No problems here. However when I click the fullscreen button, the the modal is not shown anymore. It only works in normal mode. Any suggestions how to fix this?
To see a sample see: http://jsfiddle.net/segato/e8w4wmh6/
var myCenter = new google.maps.LatLng(51.508742, -0.120850);
function initialize() {
var mapProp = {
center: myCenter,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var marker = new google.maps.Marker({
position: myCenter,
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', function () {
$('#myModal').modal('show');
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Click the marker. Then click the full screen icon and then click a marker.
The point is that fullscreen mode use fullscreen API so anything outside the fullscreen element (in this case the map DIV) remains backward.
A workaround can be to append the modal element to the map div, for example exploiting the custom controls API.
map.controls[google.maps.ControlPosition.TOP_CENTER].push(document.getElementById("myModal"));
See working fiddle.
N.B. I have disable modal background because in the maps it came out with a wrong z position, coming of top of the modal. I think would not be difficult to fix that if you need the background.
The solution proposed did not worked for me but inspired from this page it's OK : Google maps tool tip not working full screen mode
document.getElementById('map_canvas').firstChild.appendChild(document.getElement
ById("modalLarge"));

div style cursor pointer is not working in chrome

I have added custom controller to google map api.
one div in the custom controller should be clickable.
I have added cursor:pointer as the style.
It works well in firefox but not in chrome.
In chrome browser, it displays the hand icon but click action
is not working.
This is the code I added to my html file for add the html to the custom controller.
controlText.innerHTML = '<div id="newid" class="myclass" style="width:380px; margin-left:40px; margin-bottom:20px;">Click here to proceed</div></div>';
I have added to the click event listner as following.
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].clear();
map.controls[google.maps.ControlPosition.BOTTOM_RIGHT].clear();
var inputfieldControlDiv = document.createElement('div');
var inputfieldControl = new TextfieldControl(inputfieldControlDiv, map);
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(inputfieldControlDiv);
css file
.myclass{
cursor:pointer;
}
Tested it in Mozzila, Opera, IE11, Chrome and it works (it always shows the cursors specified in your class)
Here is the fiddle: https://jsfiddle.net/eugensunic/kphe5fbL/10/
I've included the following code of yours: controlText.innerHTML = '<div id="newid" class="myclass" style="width:380px; margin-left:40px; margin-bottom:20px;">Click here to proceed</div></div>'; and the clearing as well altought I believe they are not necessary.
Here is the full code JS that is in the fiddle:
var map;
var london = new google.maps.LatLng(51.508742, -0.120850);
function TextfieldControl(controlDiv, map) {
var controlUI = document.createElement('div');
controlDiv.appendChild(controlUI);
var controlText = document.createElement('div');
controlText.innerHTML = '<div id="newid" class="myclass" onclick="alert()"style="width:380px; margin-left:40px; margin-bottom:20px;">Click here to proceed</div></div>';
controlUI.appendChild(controlText);
}
function initialize() {
var mapDiv = document.getElementById('googleMap');
var myOptions = {
zoom: 12,
center: london,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(mapDiv, myOptions);
var homeControlDiv = document.createElement('div');
var homeControl = new TextfieldControl(homeControlDiv, map);
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].clear();
map.controls[google.maps.ControlPosition.BOTTOM_RIGHT].clear();
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(homeControlDiv);
}
google.maps.event.addDomListener(window, 'load', initialize);
Of-course, the cursor will switch to value "default" at some point because of your margins css set to some pixels.
EDIT
The only other issue that could make the obstruction here is that you have developer tools tab open, this has been solved in this stackoverflow thread:
url: mouse hover on anchor tag does not display pointer cursor. Behavior observed on Chrome, works fine on IE 9?
If you still have problems then you shoul reveal your TestfieldControl function.

Google map with css "transform:scale"

Good afternoon,
I have an issue with a google map and css "transform:scale".
My aim is to scale the map to 1.1 if the map is hovered. But if i do this i cant click the markern anymore. I have tried to solve it with jquery but i got no success.
Anybody here who has a solution?
Here is a fiddle: JSFIDDLE
I tought that first switch the scaled size, then load the map, and then switch to old size will get it to work, but no success.
Here is my abortive try..
$("#map").hover(function(){
$("#map").width(880).height(617.1).load('/index.html', function () {
initialize();
}).width(800).height(561);
});
Thanks for helping
Manuel Strohmaier
The problem is quite easy to explain, but unfortunately I haven't good solution now.
Take a look: http://take.ms/2E3fV
On image I mark rectangle which shows where exactly is now an element wchich responds for a click action on google map marker. So simply, when You scale map with CSS, each image scales too but position coordinates (left, right, top, bottom) don't change.
Theoreticaly You can inspect Google Map's code and fix this position in any way, but:
it's not universal solution (not for dynamic pin for example)
it can be changed in future (class name, or even whole solution)
it's rather hack than solution
what's your intens using transform:scale ?
why don't you use zoom for that ?
check my code snippet i edited from yours, may be this help you...
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882, 131.044922);
var myLatlng2 = new google.maps.LatLng(-22.363882, 125.044922);
var mapOptions = {
zoom: 4,
center: myLatlng
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var contentString = "Pls help me to get the right position :)"
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker1 = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'First Marker'
});
var marker2 = new google.maps.Marker({
position: myLatlng2,
map: map,
title: 'Sec Marker'
});
google.maps.event.addListener(marker1, 'mouseover', function () {
map.setZoom(14);
infowindow.open(map, marker1);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
#map {
height: 400px;
width: 400px;
margin: auto;
padding: 0px;
top:100px;
}
.scale {
transition: all .2s ease-in-out;
}
#map.scale:hover {
transform: scale(1.9);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<body>
<div id="map" class="map scale"></div>
</body>

google maps v3 change size of infowindow

I would like to set the size of an infowindow to fit the content inside. The standard infowindow is too wide I tried to use maxWidth but it doesn't seem to work. What is the best way to resize an infowindow?
see code:
window.setContent( inspStates[i].name+ "<br/>"+"total: "+inspStates[i].totalInsp+ "<br/>"+ info);
the information that will be displayed in the bubble looks like this( \n means next line)
NY \ntotal 60 \n2009: 10 \n2010: 20 \n2011: 30
What you want to do is replace the "standard" Googlemaps infoWindow with your own, and put your content into it. Once you replace the standard GM infoWindow, you have a lot of latitude to work with. What I did is this:
Add a new style ID called #infoWindow, and set its width.
#infoWindow {
width: 150px;
}
Outside of any functions within my Javascript, I create a new infoWindow:
var infoWindow = new google.maps.InfoWindow();
Create a new var within the function that sets the information displayed by the marker(s), and set its value to the content:
var html = '<div id="infoWindow">';
html += 'NY<br />total 60<br />2009: 10<br />2010: 20<br />2011: 30';
html +='</div>';
Call the createMarker function using the location information you would have created elsewhere, and include the html var as one of the arguments:
var marker = createMarker(point,name,html);
The createMarker function you would declare elsewhere, which would bring all of the information together, display the marker on your map, and display the information above when it's clicked on:
function createMarker(latlng,name,html) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(contentString);
infoWindow.open(map,marker);
});
}
Just so everyone is clear, if they stumble on this thread.
All you need to do is set the height and width of a container in the your info window content.
You don't need to override google classes and you don't need to get overly complicated about this.
var contentString = '<div class="map-info-window">'+
'<h1>My Info Window</h1>'+
'<p>Hello World</p>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString, });
In my css I have this:
.map-info-window {
width:200px;
height:200px;
}
That's it. That's all you need to do to set the width of a Google Maps InfoWindow.
For me this CSS works fine:
.gm-style-iw {
width: 324px !important;
height: 120px !important;
}
please take a look at following API references and examples:
Google Map V3 Examples:
https://developers.google.com/maps/documentation/javascript/examples/
Google Map V3 API Ref:
https://developers.google.com/maps/documentation/javascript/reference#MapOptions
To set the size of the bubble info-window inside a google map it's enough to add the following css in your CSS file:
.gmap-popup {
max-width:204px;
max-height:110px;
}
Adapted from this discussion.
JFrancis answers is the right one, just don't forget to add "!important" in your CSS when you set the width! This might look like a minor thing, but if you don't do it, your CSS will simply get overwritten!
#infoWindow {
width: 150px !important;
}

Resources