I'm very basic at programming and require that option just for one specific project.
I'd love to change content of one master popup by clicking on different markers.
Thing is, I have 0 clue how to get .setContent() of popup on different marker, using .on('dblclick') my marker.
I was thinking about giving value to a variable depending on marker number, and then filling one specific popup with info regarding variable number.
I intentionally skipped code block as it wouldn't bring anyone closer to the problem I have. I added my 'project' on jsfiddle.
Thanks!!!
My project on jsfiddle
var map = L.map('map').setView(center, 11);
var popupMaster = L.popup({
closeOnClick: false,
autoClose: false,
closeButton: false
})
.setLatLng([54.451194, 18.744001])
.setContent('Show text here')
.openOn(map);
var marker1 = L.marker([54.351194, 18.644001], {
title: "F-25",
opacity: 0.5
})
.addTo(map)
.bindPopup(popup1)
.on('mouseover', function(e) {
this.openPopup();
this.setOpacity(1.0);
})
.on('mouseout', function(e) {
this.closePopup();
this.setOpacity(0.5)
});
You already have the master popup in a variable, so you can update the content from a dblclick event on another marker like this
marker.on("dblclick", function(e) {
popupMaster.setContent("New content here");
});
Thats it I want to create an onclick event on my marker, I'm using angular-openlayers-directive.
So far I've been able to make some markers show up, but I'm unable to get them after a click event.
I would like to perform some actions with these markers custom properties like name, remarks, etc. But it seems too hard to achieve this with openlayers 3.
<openlayers ol-center="ven" height="100vh">
<ol-layer ol-layer-properties="wms">
<ol-marker ng-repeat="marker in markers"
lat="marker.lat"
lon="marker.lon"
></ol-marker>
</ol-layer>
</openlayers>
So how could I handle an onclick event on these markers and get all their info, or a reference to the javascript object "marker" itself.
I wasn't sure if you wanted to have the click on the popover or the marker itself. Below there are instructions for both. Use the Plunker link at the bottom to see a working demo of both options.
To Register Click on Marker Popover:
If you take a look at the directive, you can see that the marker template uses ng-transclude, so you can do the following:
Markup:
<ol-marker ol-marker-properties="santiago" >
<p ng-click="showDetails(santiago)">Santiago de Compostela</p>
</ol-marker>
In your controller:
$scope.showDetails = function(id) {
alert('lat: '+ id.lat+', '+'lon: '+id.lon);
};
Here I'm passing in the marker object to the showDetails function. When you click the popover label for Santiago de Compostela in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
To Register Click on the Marker:
You can add an onClick property to the marker object as follows:
In your controller:
finisterre: {
lat: 42.907800500000000000,
lon: -9.265031499999964000,
label: {
show: false,
},
onClick: function (event, properties) {
console.log(properties);
alert('lat: '+ properties.lat+', '+'lon: '+properties.lon);
}
}
When you click the marker associated with finisterre in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
NOTE:
I could only get this to work though under the following conditions:
The marker object must have a label property defined
The show property of the label must be set to false.
The ol-marker html element must have some transcluded content OR the message property must be set in the marker label object.
I was able to use CSS to prevent the popover from displaying as you can see in the demo, but it seems a little hacky. If you want the popover to display on click as well, you're all set, just remove the css hidden class I added and add your pop-over html.
Plunker Demo
I just got this working today as it happens. What I am doing for now is adding the properties to my markers once I get them from mongo.
function addMarkerProperties ()
// needed to enable click events on a marker!
// Have a label property defined for the marker.
// Have the show property of the label set to false.
// Have some transcluded content in the marker.
{
for (var i = $scope.markers.length - 1; i >= 0; i--) {
$scope.markers[i].onClick = function (event, properties) { console.log('Clicked a marker'); console.log(this); console.log(properties); };
$scope.markers[i].label = {
// Note: Duplication of data here # message. Fix this later.
"message": $scope.markers[i].name,
"show": false,
"showOnMouseOver": false
};
};
}
Once the markers have all the properties they need. It just sort of works but I do have a bug to iron out as well where the marker titles repeat above the map for.... reasons.
As you click the markers the words disappear.
With the latest release (April 6 2016) of the angular-openlayers-directive library (correct) ngClick-handling seems to be implemented. After a bit of searching I came up with the following solution:
The HTML (simplified):
<html ng-controller="mapController">
<openlayers width="100%" height="400px">
<ol-marker ng-repeat="marker in markers" ol-marker-properties="marker" ng-click="showDetails(marker)"></ol-marker>
</openlayers>
</html>
The Angular Javascript for the map controller (expects that your API endpoint called '/api/markerlist' returns a list of JSON objects with the fields: 'latitude', 'longitude'):
$scope.markers = [];
$scope.initializeMarkers = function() {
var markerList = $http.get("yoursite/api/markerlist")
.succes( function(result) {
angular.forEach(result, function(value, key) {
$scope.markers.push({
lat: value.latitude,
lon: value.longitude,
label: {
message: "Your message",
show: false,
showOnMouseOver: false
}
});
});
}
function showDetails(marker) {
alert('Clicked a marker on the map');
console.log(marker);
}
Finally, be sure that you have included the angular-openlayer-directive CSS, so the messages for the labels are not visible.
I am using jQuery with a Google Maps Listener. I have boxes in my map and I need to make changes on them when they are too close.
The problem is the next one:
I check if the boxes are close and then make them red (for example). I know the condition is OK because I have a "console.log" and everything is nice. Here is my code:
Little explanation:
A marker is an element in the map. Every marker has his own infobox (the boxes in the map I want to change).
A cluster is a group of markers.
clusterListener2 = google.maps.event.addListener(markerCluster, 'click', function (clusterer) {
zoomLimit=12;
var myzoom = map.getZoom();
var olderPosk=1000000;
var olderPosD=1000000;
if (myzoom>zoomLimit) {
clusterClickController=1;
$.each(clusterer.getMarkers(), (function (index, marker) {
var restak=olderPosk-marker.position.k;
var restaD=olderPosD-marker.position.D;
if (restak<0) restak=restak*(-1);
if (restaD<0) restaD=restaD*(-1);
if ((restak<0.0001)&&(restaD<0.0001)) {
console.log("Close elements");
console.log($(this.infobox));
currentInfobox=$(this.infobox);
currentInfobox.css({"background" : "red"});
}
olderPosk=marker.position.k;
olderPosD=marker.position.D;
marker.marker.open(map, this);
marker.infobox.open(map,this);
marker.marker.isHidden = false;
}));
}
else {
clusterClickController=0;
}
});
So, the "Close elements" console.log is appearing in console and the $(this.infobox) prints a jQuery element but when I do the "background red" statement it does not work.
Any help? Thanks
I think you should use infobox.content_.style.cssText to set the new style instead. As it is shown in line 44 of this jsfiddle.
From what I see, in v2 of GMaps API there was a property "buttons" of the InfoWindow object that one could define in a way that given InfoWindow has no close button:
marker.openInfoWindowHtml("No Close Button",{buttons:{close:{show:4}}});
The above however does not apply for v3. Does anybody know a way to do it? I read about an utility that replaces InfoWindow called InfoBox but it has not been developed for the past 2 years. I'm currently using the latest 3.13 version of Gmaps v3 API.
A workaround with jQuery is acceptable, if there is no better solution.
You can also do it through the css.
.gm-style-iw + div {display: none;}
edit january 2019
as #antmeehan said in the comment,
Google have changed the HTML, and the close button is now a button element rather than a div
So the css code to hide the "x" button is now:
.gm-style-iw + button {display: none;}
Update
Displaying a <div> on top of a google map is straight forward :
example css:
div.info {
position: absolute;
z-index: 999;
width: 200px;
height: 100px;
display: none;
background-color: #fff;
border: 3px solid #ebebeb;
padding: 10px;
}
A info class <div> somewhere in the markup :
<div id="myinfo" class="info"><p>I am a div on top of a google map .. </p></div>
Always nice to have a short reference to the div :
var info = document.getElementById('myinfo');
The more tricky part, showing the <div>, how and when - here I just assign a click handler to the map (after it is created) and show the info <div> at mouse location XY inside the map :
google.maps.event.addListener(map, 'click', function(args) {
var x=args.pixel.x; //we clicked here
var y=args.pixel.y;
info.style.left=x+'px';
info.style.top=y+'px';
info.style.display='block';
});
What you gain with this is, that the info <div> follows you around on the map, every time you click.
You will need more styling so it suits your need, eg so it "looks like an InfoBox", but that should be easy to find out, I am not a librarian :)
And maybe later on something to close the info with, but that you didn't want in the first place :)
Original answer
You cant! There is no way to do this in the current v3.13 InfoWindow options.
A workaround is to disable the image containing the X :
<style>
img[src="http://maps.gstatic.com/mapfiles/api-3/images/mapcnt3.png"] {
display: none;
}
</style>
But this is in no way advisable!
src="http://maps.gstatic.com/mapfiles/api-3/images/mapcnt3.png is just what the infowindow is referring to today. Tomorrow, or in a month, or in a year, this image-reference for sure has changed. As you can see if you search for similar "solutions", made over time - like this. They are all broken today, eg the effort is meaningless.
I think there is extremely good logic in google "refusing" to follow the request for hiding the close-button. If you not need a close-button, what do you need an InfoWindow for anyway? When you are better off just to show a <div> on the map.
if using jquery just add this
$(".gm-style-iw").next("div").hide();
To extend on Louis Moore's answer, you can also center the text after removing the close button:
.gm-style-iw + div {display: none;}
.gm-style-iw {text-align:center;}
Without Centering:
With Centering:
Thanks Tushar, but also you need put this code in event handler
google.maps.event.addListener(infowindow, 'domready', function(){
$(".gm-style-iw").next("div").hide();
});
I used the answer given by Tushar Gaurav, but expanded it a little...
$(".gm-style-iw:contains(" + infoText + ")").css("left", function() {
return ($(this).parent().width() - $(this).width()) / 2;
}).next("div").remove();
That will remove the X from an infowindow with the text in infoText, and then recenter the text as it's off-center after removing the close button.
Just adding this for anyone else who stumbles across this page as I did.
It should be .gm-style-iw > button to avoid other custom buttons we might have within the box to be hidden too:
.gm-style-iw > button {
display: none !important;
}
closeBoxURL: ""
as stated before doesn't apply for InfoWIndow. This is an option on the InfoBox.
You may for example use this CSS workaround to remove the X, and the surrounding clickable button:
.gm-style-iw + div {
display: none;
}
And as davidkonrad said. This is a workaround on the code as it is today. It will likely be changed.
My own way (without Jquery) and with realign to the center of the infoWindow:
var content = document.querySelector('.gm-style-iw');
content.parentNode.removeChild(content.nextElementSibling);
content.style.setProperty('width', 'auto', 'important');
content.style.setProperty('right', content.style.left, 'important');
content.style.setProperty('text-align', 'center', 'important');
This works
.gm-style-iw > button {display: none !important;}
My solution:
google.maps.event.addListener(marker, 'click', function() {
var wnd = new google.maps.InfoWindow({
content: "<table id='viewObject' >...</table>"
});
google.maps.event.addListener(wnd, 'domready', function(){
$("#viewObject").parent().parent().next().remove();
});
wnd.open(map, marker);
});
============= HTML ==============
<agm-map #gm [latitude]="lat" [longitude]="lng" #AgmMap [fitBounds]="true">
<agm-marker
(mouseOver)="onMouseOver(infoWindow, gm)"
(mouseOut)="onMouseOut(infoWindow, gm)"
>
<div id="test">
<agm-info-window #infoWindow></agm-info-window>
</div>
</agm-marker>
</agm-map>
============= TS ==============
onMouseOver(infoWindow, gm) {
console.log(infoWindow);
if (gm.lastOpen != null) {
gm.lastOpen.close();
}
gm.lastOpen = infoWindow;
infoWindow.open();
setTimeout(() => {
var x = document.getElementsByClassName('gm-ui-hover-effect')[0].remove();
}, 10);
}
onMouseOut(infoWindow, gm) {
gm.lastOpen = infoWindow;
// infoWindow.close();
}
You can use this. This will not hide other images like zoom control, pan control etc.
on dom ready of info window you can use this.
google.maps.event.addListener(infoWindow, 'domready', function () {
document.querySelector(".gm-style-iw").nextElementSibling.style.display = "none";
});
I can't find correct answer in here, so I fixed it myself. It will work well.
google.maps.event.addListener(infowindow, 'domready', function(){
$(".gm-style-iw").parent().find("button").removeAttr("style").hide();
});
.gm-style-iw + button {display: none !important;}
Anno domini 2021 this work better for me
button.gm-ui-hover-effect {
display: none !important;
}
I couldn't get any of the $(".gm-style-iw").next("div").hide(); answers to work even when calling the code after the DOM was loaded, since there was a delay between the code being called and the info window being created. What I did was create an interval that runs until it finds the info window and removes the "X" element. If there's a better way please tell me.
var removeCloseButton = setInterval(
function()
{
if ($(".gm-style-iw").length)
{
$(".gm-style-iw").next("div").remove();
clearInterval(removeCloseButton);
}
},
10
);
Using Archers method I need to do
$(".gm-style-iw").css("left", function() { //remove close and recenter
return ($(this).parent().width() - $(this).find(">:first-child").width()) / 2;
}).next("div").remove();
google.maps.event.addListener(infowindow, 'domready', function() {
var iwOuter = jQuery('.gm-style-iw');
// Reference to the div that groups the close button elements.
var iwCloseBtn = iwOuter.next();
// Apply the desired effect to the close button
iwCloseBtn.remove()
});
As there is no option to hide this by API parameter, you have to find the element by targeting the content window and remove it.
Hope this helps :)
in jQuery's gmap3 plugin this can be accomplished using
google.maps.event.addListener($('#map').gmap3({get:{name:"infowindow"}}), 'domready', function(){
$(".gm-style-iw").next("div").remove();
});
May 2021 : Add this in your CSS:
button.gm-ui-hover-effect {
visibility: hidden;
}
This worked perfectly with Maps API v3.43
Inspect it - it's a div with a class of close on it - you can target it with CSS and set it to display: none;
You can just use the option
closeBoxURL : ""
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html
From Google Documentation
closeBoxURL | string | The URL of the image representing the close box. Note: The default is the URL for Google's standard close box. Set
this property to "" if no close box is required.
Example
var infowindow = new google.maps.InfoWindow({
closeBoxURL: "",
closeBoxMargin : ""
});
You can set "closeBoxURL" property of the Info Window to "" and it will make the button disappear.
var infowindow = new google.maps.InfoWindow({
content: contentString,
closeBoxURL: ""
});
I'm working with Google Maps API V3, and I'd like to display a clickable image near to a drawed polygon when the mouse hovers it.
Until now, I'm able to create this event, but I have no idea how to display this image near to my polygon. Ideally, I'd like this image appears where the mouse entered in the polygon.
Here is a piece of my code, but it's just a try and the image is not displayed, so it is very incomplete (and maybe wrong). You can suggest me to do otherwise, Javascript is not my preferred language...
google.maps.event.addListener(polygon, 'mouseover', function(e) {
this.setOptions( {fillOpacity: 0.1} );
polygon["btnMyButtonClickHandler"] = {};
polygon["btnMyButtonImageUrl"] = MyImage;
displayMyButton(polygon);
});
function displayMyButton(polygon) {
var path = polygon.getPath();
var myButton = getMyButton(path.btnMyButtonImageUrl);
if(myButton.length === 0)
{
console.log("IN"); //Is displayed in the console
var myImg= $("img[src$='http://linkToMyImage.png']");
myImg.parent().css('height', '21px !important');
myImg.parent().parent().append('<div style="overflow-x: hidden; overflow-y: hidden; position: absolute; width: 30px; height: 27px;top:21px;"><img src="' + path.btnMyButtonImageUrl+ '" class="myButtonClass" style="height:auto; width:auto; position: absolute; left:0;"/></div>');
// now get that button back again!
myButton = getMyButton(path.btnMyButtonImageUrl);
myButton.hover(function() {
$(this).css('left', '-30px'); return false; },
function() { $(this).css('left', '0px'); return false; });
myButton.mousedown(function() { $(this).css('left', '-60px'); return false;});
}
// if we've already attached a handler, remove it
if(path.btnDeleteClickHandler)
myButton.unbind('click', path.btnMyButtonClickHandler);
myButton.click(path.btnMyButtonClickHandler);
}
function getMyButton(imageUrl) {
return $("img[src$='" + imageUrl + "']");
}
Thanks for your suggestions !
EDIT
#MrUpsidown, unfortunately no, click event can't be a solution, I really need your Something here div appears at mouseover.
I modified your code like this :
google.maps.event.addListener(polygonPath, 'mouseover', function (event) {
if( $("#map_overlay").css('display') == "none")
{
$("#map_overlay").css({
'position': 'absolute',
'display': 'block',
'left': event.Sa.pageX,
'top': event.Sa.pageY
});
}
});
The div appears when my mouse enter the polygon and don't move except if my mouse hovers the div (which hovers the polygon). On this case, the event seems called continuously. How can we avoid this and let the div at its inital position once the mouse enter the polygon ?
Here is your modified : fiddle
You need to create an element to hold your clickable image. Make it position:absolute; with a bigger z-index than your map container. To place it at a specific place, check the mouse position on your polygon mouseover event and set the element position accordingly. Hope this helps.
Edit: Yes, wrap it in a DIV is a good idea. Here is a simple fiddle to show the concepts. And sorry, of course it was mouseover and not mouseenter like I first wrote.
http://jsfiddle.net/upsidown/zrC2D/