Backbone Marionette Google Maps infowindow button event - google-maps

I know how to display an infoWindow, but I have a problem capturing the event from a button displayed there.
var view = Marionette.LayoutView.extend({
...
methodA: function(){
me.showMapInfoWindow(marker, "Test popup<button onclick='methodB()'>Click me</button>")
me.infoWindow.open(me.map, marker);
},
methodB: function(){
console.log("test");
}
}
When I click the button, I get an error when calling methodB saying it's not defined. I've tried with me.methodB, etc...but no luck there. How can I fix this?

Here is a JSFiddle showing an InfoWindow populated with a DOM node, rather than a HTML string. This way, we can use jQuery to add a programmatic event to the DOM, which can access the current scope, as shown.
var $infoWindow = $('<div>Test popup<button>Click me</button></div>');
$infoWindow.find('button').click(_.bind(this.methodB, this));
me.showMapInfoWindow(marker, $infoWindow.get(0));
me.infoWindow.open(me.map, marker);
Answer to First Question
Here is a JSFiddle showing an InfoWindow firing a global function. In this case I had to set the function to Window scope, though I believe this is due to the JSFiddle environment.
window.myFunction = function() {
window.alert("function fired!");
}
...
var html = '<button onclick=\'myFunction()\'>Click me</button>';
if you want to debug the scope, I'd suggest using the debugger statement:
var html = '<button onclick=\'debugger;\'>Click me</button>';

Related

how to detect div value (Django rendered) change with MutationObserver

I am rendering a value from django backend to frontend, and I am trying to detect the div value change with MutationObserver. Below is my current code:
MutationObserver part:
window.addEventListener('load', function () {
var element = document.getElementById('myTaskList');
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(myFunction);
observer.observe(element, {
childList: true
});
function myFunction() {
console.log("this is a trial")
console.log(element);
console.log(element.innerHTML);
}
// setTimeout(function(){
// element.innerHTML = 'Hello World!';
// }, 1000);
//
// setTimeout(function(){
// element.innerHTML = 'Hello Space!';
// }, 2000);
});
html part:
<div hidden id="myTaskList">{{resultList | safe}}</div>
I am rendering a string "dummyValue" to the div, but just don't see the value from the console.log() statements inside function.
this works well when I uncomment the setTimeout functions though.
Thanks for any help on why MutationObserver won't detect the rendered div value
I finally figured out the reason. Hope this might be helpful for people having similar issues in the future.
So, basically I was using my Django form submit button to do two actions at one time:
1. submit data to the view and process the data in the view;
2. trigger another function with the click action through
Ajax.
The second action was blocked by the first action, and I was only able to get result from action 1.
My solution: I modified action 1 to use Ajax as well. As I mentioned above, I originally used the Django form to submit data. I trigger action 2 inside the success function of action 1. Everything is working well now.

Events are not being triggered when using Template.myTemplate() in Meteor

I'm trying to catch a click button event inside a google maps InfoWindow. To do so I have the following
<!-- Html file -->
<template name="infoWindowContent">
<button>Click Me!</button>
</template>
Then I have this on the client.js
//Client js file
//Function that renders the template. Gets called from a user's action
function showInfoWindow(map, marker) {
var infoWindow = new google.maps.InfoWindow();
//This is the line that generates the template's html
var infoWindowHtmlContent = Template.infoWindowContent();
infoWindow.setContent(infoWindowHtmlContent);
infoWindow.open(map, marker);
}
//Template events
Template.infoWindowContent.events = {
'click button': function(event){
console.log('event was triggered', event);
}
}
The infoWindow is shown on the map and it contains the button, but when the button is clicked no log is displayed in the console. Any clue on this? How can I catch an event dispatched by some element rendered using Template.myTemplate()?
Function Template.template() returns plain html string. It doesn't have any Meteor properties enabled. What you need is a DOM element with proper behavior injected.
...
var node = Meteor.render(Template.infoWindowContent());
outerElement.appendChild(node);
...
I'm not sure how to use DOM node in google maps api, but if it's possible, it should be easy.
Also, use the proper events form, it saves much trouble in the long run:
Template.infoWindowContent.events({
...
});

Google Maps V3 Infobox undefined on polygons

I have a spoke in my wheels and I am not sure how to sort this out. I have been struggling with it for a couple days and it isn't like a normal infobox as it is not set to a marker rather a polygon which is something new for me. I have polygons that display with data from an XML file and they show up fine. I have searched the web and got it to have the mouseover set up to where you mouseover a polygon the opacity changes and an infobox pops up. Problem is the infobox when it pop up shows "undefined" instead of the html I have set in it to display with data from the XML file.
Here is a link to the test map for example.
http://www.mesquiteweather.net/googlemap_poly.html
Here is a link to the XML file where I am just trying to show the elements events and expires in the info box.
http://www.mesquiteweather.net/xml/warnings_test.xml
This is the code I am working with to create the infoboxes and mouseover events
function attachPolygonInfoWindow(polygon, html, event, expires)
{
var html = "<strong>" + event + "</strong>";
eventWarnings.infoWindow = new google.maps.InfoWindow({content: html});
google.maps.event.addListener(eventWarnings, 'mouseover', function(e) {
var latLng = e.latLng;
this.setOptions({fillOpacity:80});
polygon.infoWindow.setPosition(latLng);
polygon.infoWindow.open(map);
});
google.maps.event.addListener(eventWarnings, 'mouseout', function() {
this.setOptions({fillOpacity:0.35});
polygon.infoWindow.close();
});
}
var polygon = new google.maps.Polygon(/* omitted for brevity */);
attachPolygonInfoWindow(eventWarnings);
eventWarnings.setMap(map);
}
});
I am pretty sure it is something easy I am overlooking but I haven't been able to find anything that pertains to my issue. I am just lucky I got the infobox to show at all as I have learned it's tricky since polygons don't have a true center and they are not set up like you would with a marker which I can handle.
If anyone has any suggestions please let me know.
-Thanks
You defined your attachPolygonInfoWindow function with 4 argument, but only provide one when you call it:
// definition
function attachPolygonInfoWindow(polygon, html, event, expires)
...
// call
attachPolygonInfoWindow(eventWarnings);
Probably you want (I don't see the html or expires parameters being used):
attachPolygonInfoWindow(eventWarnings, "", event, null);
The other option would be to change the definition to:
// definition
function attachPolygonInfoWindow(polygon, event, expires)
and the call to (assuming you are going to use "expires" for something):
attachPolygonInfoWindow(eventWarnings, event, expires);
As it doesn't look like you need to pass in that parameter (event is serving the function that I would expect it to serve).
Also, FYI, you have a "hanging comma" in your alertColors.js which make IE unhappy...
example

How to identify a google map marker on click?

I'm creating a Google Map from the developer API v3. It's populated with markers created dynamically from ColdFusion querying an MsSQL database.
<cfloop query="One">
<script>locations[<cfoutput>#One.userID#</cfoutput>
] = new google.maps.LatLng(<cfoutput>#One.latLng#</cfoutput>);
</script>
</cfloop>
I need a way to recognise the marker when its clicked so I can display address details in a box below the map and also higlight markers when a button is clicked lower on the page.
In general, you would typically assign your own custom properties to the Marker. Something like:
function markerClicked(e) {
console.log('Marker ' + marker.myData + ' has been clicked');
}
var marker = new google.maps.Marker(...);
marker.myData = 1; //this could be arbitrary data or even another object
google.maps.event.addListener(marker, 'click', markerClicked);
Adding custom data to any Google Maps API object has risks though. Google's code is obfuscated and the internal (non-documented) properties can and do change. Make sure your property is named in such a way that it won't conflict with any existing property or future property. Tip: Choose a property name longer than 3 letters.
If you are going to minify/compile/compress your maps code, then there are additional considerations.
What about :
google.maps.event.addListener(marker, "click", function (e) {
var clicked = this;
//...
});
This is pretty thoroughly documented/explained in the documentation.
https://developers.google.com/maps/documentation/javascript/overlays#InfoWindows
When you create markers, add dom listeners to the markers like this
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});

How can I bind click event to custom overlay with Google maps v3 both in IE and Firefox

I've already subclass my overlay object under the instruction of google document, and my onAdd() function is listed below:
MyOverlay.onAdd() {
var div_parent = document.createElement("DIV");
var div_child = document.createElement("DIV");
div_child.innerHTML = "Click Me";
div_parent.appendChild( div_child );
this.getPanes().overlayLayer.appendChild(div_parent);
var this = that;
google.maps.event.addDomListener( div_parent, 'click', function(){
google.maps.event.trigger(that, 'click'); // from [http://stackoverflow.com/questions/3361823/make-custom-overlay-clickable-google-maps-api-v3]
alert("Clicked");
} );
}
My code can work well ONLY in IE, but in Firefox and Chrome, the click event will not be triggered anymore.
So how to solve the problem?
Instead of using overlayLayer mapPanes, you should use overlayMouseTarget.
Reference: http://code.google.com/apis/maps/documentation/javascript/overlays.html#CustomOverlays
I know this is an old post, but if you were wondering, here is the solution:
In your code above, you need to change the overlay function from:
this.getPanes().overlayLayer.appendChild(div_parent);
to:
this.getPanes().overlayMouseTarget.appendChild(div_parent);
Also note although your click events will be captured on desktop even if you use overlay pane, for touch events to work, mouse target pane is necessary.