add event handler an element inside a info window google maps v3 - javascript

hi I'm trying to add to button inside an info window an event i tried like this
var infoWindow = new google.maps.InfoWindow({
content: '<div></br><span class="formatText">Ubicacion del Marcador: </span>' + event.latLng.toString()
+ '</br> <input type="button" id="btnPrueba" value="prueba"/></div>'
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, this);
google.maps.event.addDomListener(document.getElementById('btnPrueba'), 'click', removeMarker);
});
function removeMarker(){
alert('it works');
}
What am i doing wrong? or it's another way to do this?. Thanks
Edit
I'm also tried with jquery like this but although the event it's get by the function the alert doesn't show. When i do the debug with chrome it's works :(
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, this);
$("#btnPrueba").click(function () {
alert('funciona');
});
});

Try the "onclick" attribute for the button.
'<input type="button" id="btnPrueba" value="prueba" onclick="removeMarker()"/>'

Calling a global function like #DeeV's shown really does seem like the straightest shot at this (except for dirtying the global namespace a smidge which is looked down on these days). jQuery event delegation does work without any additional setTimeout gymnastics but feels like a heavier function call stack to accomplish the same goal. e.g.
$("#myMapContainer").on("click", "#btnPrueba", function() {alert "it works";});
However, sticking with the global approach, on top of #DeeV's answer, often the trick is getting some contextual values that you can act upon in that event handler:
one way is embedding parameter values to the function call in the
InfoWindow content string
along those lines, as you generate each Marker, push
it's reference to an array (also necessarily global) and thereby facilitate
Marker API calls later in the handler (e.g. setIcon(), etc.)
e.g. JS Pseudocode
var myMarkerArray = [];
function removeMarker(markerIndex) {
myMarkerArray[markerIndex].setMap(null);
}
for(int i=0; i<myLocationData.length; i++) {
var marker = new google.maps.Marker({...});
myMarkerArray.push(marker);
var popup = new google.maps.InfoWindow({ content: '<input type="button" id="btnPrueba" value="prueba" onclick="removeMarker('+i+')"/>' });
}

My workaround was to use a short timeout.
var infoWindow = ... (as in your question) ...
infoWindow.open(...);
setTimeout(function(){
$('#btnPrueba').on('click', function(e){
alert("It works at last!");
});
},50); //Wait for 0.05s
When I didn't use the setTimeout wrapper it did not work. Even though setContent() and open() had already been called. I assume this means the creation is done asynchronously.
NOTE: the "50" is a magic number, so potentially brittle.
NOTE: using the following also did not work for me, which I still find strange and cannot explain:
$('#btnPrueba').on('click', document, function(e){
alert("No luck...");
});

Related

Jquery Selector fails after setContent called on info window

I have a google maps info window that I open on a map, directly after which I want to bind event listeners to parts of the html in the info window. I do this with JQuery. The code goes something like:
myInfoWindow.open(map);
$('#someIdInInfoWindow').bind({
click: function() { foo1(); },
mouseenter: function() { foo2(); }
});
Unfortunately, I think Google makes most of their libraries asynchronous, so the content of the info window is not actually set until after the JQuery selector has been called.
How can I fix this so the event handlers are properly set? Thanks!
You must wait for the domready-event of the infoWindow before you add the listeners, at this time the HTML-element representing the infowindow has been attached to the document and it's contents are accessible :
google.maps.event.addListener(myInfoWindow,'domready',function(){
$('#someIdInInfoWindow').bind({
click: function() { foo1(); },
mouseenter: function() { foo2(); }
});
});
This applies when the content of the infoWindow is set via a string, when you assign it via a node you may also add the listeners directly to the particular element when you create it:
var content = $('<div/>')
.append($('<div/>',{id:'someIdInInfoWindow'})
.text('some text')
.click(foo1)
.mouseenter(foo2));
myInfoWindow.setContent(content[0]);
myInfoWindow.open(map);

Click link inside Leaflet Popup and do Javascript

I have a leaflet map up and running. It overlays a series of polygons (via GeoJSON) on the map and attaches popups to each polygon. Each of the popups display information about that polygon.
I'd like to have inside the popup a link that, when clicked, runs a javascript function that pulls further smaller polygons via AJAX and shows them.
I can't get the script to catch a click on the link via the normal jQuery/Javascript click events. Here's what I mean by normal (the following doesn't work):
$('a .smallPolygonLink').click(function(e){
console.log("One of the many Small Polygon Links was clicked");
});
The bindPopup part is as follows. It runs on each polygon when made and it pops up correctly on clicking on a polygon. It does show the link, just won't run the above code on click.
var popupContent = "Basic Information..." + '<a class="smallPolygonLink" href="#">Click here to see the smaller polygons</a>';
layer.bindPopup(popupContent);
Here's a JSFiddle illustrating the example, though in a far simpler form. http://jsfiddle.net/2XfVc/4/
The link element inside the popup is being dynamically generated from your markup each time the popup is opened. That means the link doesn't exist when you're trying to bind the handler to it.
The ideal approach here would be to use on to delegate event handling to the popup element or an ancestor of it. Unfortunately, the popup prevents event propagation, which is why delegating event handling to any static elements outside the popup won't work.
What you can do is preconstruct the link, attach the handler, and then pass it to the bindPopup method.
var link = $('TestLink').click(function() {
alert("test");
})[0];
marker.bindPopup(link);
Here is a demonstration: http://jsfiddle.net/2XfVc/7/
In general, to insert any sort of complex markup with multiple event handlers, use the folowing approach:
// Create an element to hold all your text and markup
var container = $('<div />');
// Delegate all event handling for the container itself and its contents to the container
container.on('click', '.smallPolygonLink', function() {
...
});
// Insert whatever you want into the container, using whichever approach you prefer
container.html("This is a link: <a href='#' class='smallPolygonLink'>Click me</a>.");
container.append($('<span class="bold">').text(" :)"))
// Insert the container into the popup
marker.bindPopup(container[0]);
Here is a demo: http://jsfiddle.net/8Lnt4/
See this Git issue for more on event propagation in leaflet popups.
While the Popup content wrapper prevents event propagation, events within the popup inner Markup propagate just fine. You can add events to popup elements when they are displayed on the map (and have become part of the DOM). Just watch for leaflet event popupopen.
var map = L.map('map').setView([51.505, 10], 7); //for example
//the .on() here is part of leaflet
map.on('popupopen', function() {
$('a .smallPolygonLink').click(function(e){
console.log("One of the many Small Polygon Links was clicked");
});
});
http://jsfiddle.net/tJGQ7/2/
This works like a charm for me. If your popup does not have a 'a .smallPolygonLink' the above code does nothing.
This code runs on every startup of a popup. However you don't have to worry that it attaches more than one handler to an element, since when the popup closes, the DOM nodes get thrown away.
There is a much more general way to do this. However, it involves eval(). Use at your own risk. But when AJAXloading partial pages that contain JS you run the same risks, so for your edification I present "executing JS inside your leaflet popups":
map.on('popupopen', function(){
var cont = document.getElementsByClassName('leaflet-popup-content')[0];
var lst = cont.getElementsByTagName('script');
for (var i=0; i<lst.length;i++) {
eval(lst[i].innerText)
}
});
demo: http://jsfiddle.net/tJGQ7/4/
Now you can write:
var popup_content = 'Testing the Link: TestLink<script> $(".speciallink").on("click", function(){alert("hello from inside the popup")});</script>';
marker.bindPopup(popup_content);
That's what I find on the mapbox offical website: Create a click event in a marker popup with Mapbox.js and jQuery. The comment explains why we say $('#map') instead of $('#mybutton').
var marker = L.marker([43.6475, -79.3838], {
icon: L.mapbox.marker.icon({
'marker-color': '#9c89cc'
})
})
.bindPopup('<button class="trigger">Say hi</button>')
.addTo(map);
//The HTML we put in bindPopup doesn't exist yet, so we can't just say
//$('#mybutton'). Instead, we listen for click events on the map element which will bubble up from the tooltip, once it's created and someone clicks on it.
$('#map').on('click', '.trigger', function() {
alert('Hello from Toronto!');});
I came across this problem, tried the solution above. But it didn't worked for me. Found the following pretty basic jquery solution.
// add your marker to the map
var my_marker = new L.marker([51.2323, 4.1231], {icon: my_icon});
var popup = L.popup().setContent('<a class="click" href="#">click</a>');
my_marker.addTo(map).bindPopup(popup);
// later on
jQuery("body").on('click','a.click', function(e){
e.preventDefault();
alert('clicked');
});
You can check inner properties of popup object, including _wrapper etc.
map.on('popupopen', _bindPopupClick);
map.on('popupclose', _unbindPopupClick);
var _bindPopupClick = function (e) {
if (e.popup) {
e.popup._wrapper.addEventListener('click', _bindPopupClickHandler);
}
};
var _unbindPopupClick = function (e) {
if (e.popup) {
e.popup._wrapper.removeEventListener('click', _bindPopupClickHandler);
}
}`
You can use jQuery to select the canvas element, but you'd have to use its own methods within the canvas. A decent start would be https://developer.mozilla.org/en/canvas_tutorial .
mapbox JavaScript library has an event:
bindPopup('<button class="trigger">Say hi</button>');
addTo(map);
$('#map').on('click', '.trigger', function() {
alert('Hello from Toronto!');
});
https://www.mapbox.com/mapbox.js/example/v1.0.0/clicks-in-popups/

Use Google Maps Api Event/Listener in JQuery

ok. what i want is the following: i want to control a mouseover of a marker with jquery.
how can i do that? i have no experience with pure js. (and i don't want to use a jquery-plugin)
i tried this:
google.maps.event.addListener(marker, 'ggmouseover', function() {
marker.setIcon(pinred);
});
ggmouseover.mouseover();
this does not work. (it works with 'mouseover' instead of 'ggmouseover') i want to create a function or something i can call later through jquery.
like: $('#button').mouseover(function(){ ggmouseover(); });
how can i do this? ideas?
You can do it by using :
trigger(instance:Object, eventName:string, var_args:*)
Triggers the given event. All arguments after eventName are passed as arguments to the listeners.
Which gives, for your case :
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(pinred);
});
$("#button").mouseover(function() {
google.maps.event.trigger(marker, 'mouseover');
});

Hyperlink to open marker infowindow on Google Map

I have a map, with a side bar div next to it. I'm trying to make it so that each marker on the map has a corresponding hyperlink in the sidebar, and when clicked, the info box for that marker pops up.
function linkClick(){
google.maps.event.trigger(gmarkers[cpid], "click");
}
content += ''+tmpName+"<br>";
$("#cplist").html(content);
cpid is a unique id for every point on the map, a value which is stored in the database with the rest of the information for the markers.
I have my markers on the map, and my links in the side bar, but I'm not sure how to make the connection between to two. I've created the 'linkClick' function to try and achieve this, but I just get the error:
ReferenceError: Can't find variable: linkClick
Currently all of the above code is in the loop which plots the markers on the map. I think i've included enough detail/code.
This is an example of what I want to achieve http://www.geocodezip.com/v3_MW_example_categories.html
I suggest changing your approach - rather than trying to push the click event, just go directly to the InfoWindow and call open. Somewhere else in your code you have a click event listener for each marker that opens an InfoWindow; so maintain reference(s) to your InfoWindow instances and open them, just the same as in the marker click event handler, when the onlick function attached to the link is called.
Or, if you are following a common strategy and working with a single, global InfoWindow, just write a function that accepts the cpid, places the necessary content in the InfoWindow, sets the correct position, and then calls InfoWindow.open( map ).
So if this is your event listener code:
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(tmpName+" is "+tmpDist+"km away from you.");
infowindow.open(map, this);
});
Add a new function:
function openInfoWindow( cpidAndWhateverElseParam ) {
infowindow.setContent(tmpName+" is "+tmpDist+"km away from you.");
infowindow.open(map, this);
}
And change your link code to be:
content += '<a href="javascript:openInfoWindow(' + cpidAndWhateverElseParam +
')">'+tmpName+"</a><br>";
For function you are not passing any variable,
thats why it is giving ReferenceError: Can't find variable: linkClick
function linkClick(cpid){
google.maps.event.trigger(gmarkers[cpid], "click");
}
content += <a onClick=linkClick(' + cpid + ')">'+tmpName+"</a><br>";
$("#cplist").html(content);
I made something similar once, but instead of use an element a i used a button and like javascript pure in the event OnClick I put my event handler and it works, so in your case i tried to handle the event like this
<a onClick=linkClick(' + cpid + ')">'+tmpName+"</a>

Close Infobox when clicking on the map

I'm using the Infobox plugin for Google Maps V3 API (http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html)
Is there anyway too close the infobox when the user clicks outside the infobox like on the map?
it's actually way easier if you have your infowindow as a global variable, or at least hold one variable that represents the single infobox you want to add at a convenient place.
edit: just to clarify: it should not be window.myInfoBox for example. With global I mean a single point where you reference your infobox
google.maps.event.addListener(map, 'click', function() {
if(infowindow){
infowindow.close();
}
});
that's all :-)
You will want to use addListener()
http://code.google.com/apis/maps/documentation/javascript/events.html#EventListeners
You can adapt the code found here:
google.maps.event.addListener(_point.popup, 'domready', function() {
//Have to put this within the domready or else it can't find the div element (it's null until the InfoBox is opened)
$(_point.popup.div_).hover(
function() {
//This is called when the mouse enters the element
},
function() {
//This is called when the mouse leaves the element
_point.popup.close();
}
);
});
Src:
Google Maps API v3 Event mouseover with InfoBox plugin
You can detect a map click with this:
google.maps.event.addListener(map, 'click', function() {
});
Infobox API:
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html
This maybe useful for you..
var inside = false;
$('#foo').live('mouseenter',function(){
inside=true;
}).live('mouseleave', function(){
inside=false;
});
$("body").mouseup(function(){
if(!inside) $('#foo').remove();
});

Categories

Resources