Google Maps V3 Infobox undefined on polygons - google-maps

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

Related

Set marker visible with knockout JS ko.utils.arrayFilter

Hello guys I am trying to create an app that sets the appropriate markers visible when a knockout search is being done.
Basically the app is.
When someone does a search the list that is bellow it, filters the list and makes only the markers that are associated with the filter list visible on the map.
I have created a ko.utils.arrayFilter and I am trying to set only the item.marker.setVisible(true)
My Github link is https://github.com/Aimpotis/map3
Thank you again and much respect to the community it is helping me learn a lot
All you need is to set the visibility of the marker to match whether it is found:
if (!filter) {
// this is new
ko.utils.arrayForEach(self.listLoc(), function (item) {
item.marker.setVisible(true);
});
return self.listLoc();
} else {
return ko.utils.arrayFilter(self.listLoc(), function(item) {
var result = (item.title.toLowerCase().search(filter) >= 0)
item.marker.setVisible(result); // this is a new line
return result;
});
}
Working fiddle.
Note: unless you're supporting particularly old browsers, you can use the Array filter method rather than Knockout's arrayFilter util, and .foreach instead of arrayForEach.

Backbone Marionette Google Maps infowindow button event

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>';

backbone.js Image uploading

I'm using nodecellar to get a better understanding of backbone.js and I've come across a problem which was answered in great detail in a similar question, however, the answer doesn't seem to be working for me:
What i'm trying to do.
Using Nodecellars wineview, i'm trying to utilise the drag and drop feature, to upload an image. I've made a note of a previous very well answered question which basically states that you have to disable the default behaviour of on dragover, so I have the following in my wine view:
events: {
"change" : "change",
"click .save" : "beforeSave",
"click .delete" : "deleteWine",
"drop #profile" : "dropHandler",
"dragover #profile" : "dragover",
'dragenter #profile' : 'alertMe'
},
then my dragover event looks like this:
dragover: function(event){
console.log('drag over event called');
event.preventDefault();
},
This is fine and working as the console log is called when it fires. and the draghandler looks like this:
dropHandler: function (event) {
event.stopPropagation();
event.preventDefault();
var e = event.originalEvent;
e.dataTransfer.dropEffect = 'copy';
this.pictureFile = e.dataTransfer.files[0];
// Read the image file from the local file system and display it in the img tag
var reader = new FileReader();
reader.onloadend = function () {
$('#profile').attr('src', reader.result);
$('#picText').html('Picture added, select save to complete changes.')
};
reader.readAsDataURL(this.pictureFile);
}
The problem
The code works, however it doesn't upload the image or save the details in the model to the database. so once I move away then select the wine again the image is back to what it was originally.
I've done some research into the HTML5 fileReader api, but there isn't much on how it uploads, or where it uploads to.
And this is where I am now, I'm looking to you guys for suggestions on how to ensure the model saves the image url, and the image is uploaded to the pics folder.
How is the best way to go about this.
Is the HTML 5 fileReader API the best option to go with?
Thank you for your feedback.
Jay
You are missing in your function dropHandler the call to your model to set the property for the image you want to save.

Imitating Mouse click - point with known coordinates on a fusion table layer - google maps

I have been making a script using a fusion table's layer in google maps.
I am using geocoder and get the coordinates of a point that I need.
I put a script that changes the style of a polygon from the fusion table when you click on it, using the google.maps.event.addListener(layer, "click", function(e) {});
I would like to use the same function that I call in the case of a click on the layer, but this time with a click with the coordinates that I got.
I have tried google.maps.event.trigger(map, 'click', {latLng: new google.maps.LatLng(42.701487,26.772308)});
As well as the example here > Google Fusion Table Double Click (dblClick)
I have tried changing map with layer...
I am sorry if my question is quite stupid, but I have tried many options.
P.S. I have seen many post about getting the info from the table, but I do not need that. I want to change the style of the KML element in the selected row, so I do not see it happening by a query.
Here is the model of my script:
function initialize()
{
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
layer = new google.maps.FusionTablesLayer({
suppressInfoWindows:true,
map : map,
query : {
select: 'Местоположение',
from: '12ZoroPjIfBR4J-XwM6Rex7LmfhzCDJc9_vyG5SM'
}
});
google.maps.event.addListener(layer, "click", function(e) {
SmeniStilRaionni(layer,e);
marker.setMap(null);
});
}
function SmeniStilRaionni(layer,e)
{
...
}
function showAddress(address)
{
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var point = results[0].geometry.location;
//IMITATE THE CLICK
}
});
}
In response to geocodezip
This way you hide all the other elements... I do not wish that. It is like if I want to change the border of the selected element. And I do not wish for a new layer.
In the function that I use now I push the style of the options of the layer and then set the option. I use the e from google.maps.event.addListener(layer, "click", function(e)); by inserting e.row['Name'].value inside the where rule.
I would like to ask you if there is any info on the e variable in google.maps.event.addListener(layer, "click", function(e));
I found out how to get the results I wanted:
For my query after I get the point I use this:
var queryText ="SELECT 'Районен съд','Окръжен съд','Апелативен съд','Местоположение' FROM "+FusionTableID+" WHERE ST_INTERSECTS(\'Местоположение\', CIRCLE(LATLNG(" + point.toUrlValue(6) + "),0.5));";
queryText = encodeURIComponent(queryText);
document.getElementById("vij query").innerHTML = queryText;
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
And then I get these results:
var rsyd = response.getDataTable().getValue(0,0);
var osyd = response.getDataTable().getValue(0,1);
var apsyd = response.getDataTable().getValue(0,2);
And then, I use the following:
where: "'Районен съд' = '"+rsyd+"'",
Which is the same as:
where: "'Районен съд' = '"+e.row['Районен съд'].value+"'",
in the click function.
This is a working solution for my problem.
But still, I cannot find a way to Imitate a Mouse click.
The issue is this: the data(row) for the layers will be requested via AJAX when you click on a layer.
In theory it's possible to select a geometry(polygon) by a given LatLng, the geometry-library has a method for this: google.maps.geometry.poly.containsLocation().
Unfortunately the FusionTableAPI does not support such queries(ST_CONTAINS), you cannot select a row by supplying a LatLng and selecting the rows where the geometry contains the LatLng.
So what you can do: create a copy of the table that contains the columns needed to select a row(Община...the distinct value, and Местоположение.... the geometry). This copy may be requested via AJAX, but when the FusionTable will not be modified anymore I would suggest to use a hardcoded copy.
What to do now when you want to simulate the click:
Iterate over all rows of the copy, use the mentioned containsLocation()-method to check if the geometry(Местоположение) contains the LatLng and when it does apply the query by using the value of the distinct column Община .
Of course it would take some time to check all the geometries, but the FusionTable is not very large, it should be a possible approach in your case.
Here is a demo: http://jsfiddle.net/doktormolle/sSwj3/
The size of the stored data is approximately 500kb, you should store the data in an external script, so they may be cached.
You may notice that the highligthning of the selected layer will be much faster when triggered via the links, because there will no data be requested via AJAX. When the highlightning of the selected feature is the only thing you need you may ommit the observation of the layer-click completely and observe the map-click instead. Use the returned LatLng to retrieve the selected row from the data and set the style:
Demo: http://jsfiddle.net/doktormolle/swdX8/

Move Ember object from one list to another with drag-and-drop

I'm trying to drag Ember objects from one list to another. If I drag an item to a new list, the item should be removed from its current list and moved to the new one.
Thanks to Drag&Drop with Ember.js and Ember.js - drag and drop list, I figured out how to copy an item to a different list. However, I am unable to determine from which list a dragged object originated. I have dozens of lists on the page, so I'd rather not do a O(n*k) search for the original object.
Currently, I'm using Ember views and the HTML 5 API. It seems like the Handelbars action helper should achieve my goal more easily. Ember's action supports the drop event, but I can't get it to fire: {{ action foo on="drop" }}. It probably has something to do with the nuanced event propagation defaults of the HTML 5 drag-and-drop implementation.
If you know how to solve this problem using actions instead of views, I'd much prefer that solution.
Here's how I'm currently transferring objects:
// this is heavily inspired by http://jsfiddle.net/ud3323/5uX9H/
// Draggable items
App.ItemView = Ember.View.extend({
templateName: 'item',
attributeBindings: 'draggable',
draggable: 'true',
dragStart: function(event) {
var dataTransfer = event.originalEvent.dataTransfer;
// The view's context is the item to transfer
var item = this.get('context');
// Use HTML 5 API to transfer object as JSON.
// There must be a more elegant way to do this.
dataTransfer.setData('application/json', JSON.stringify(item));
}
});
// Item list drop zone
App.ItemListView = Ember.View.extend({
templateName: 'itemList',
dragEnter: function(event) {
event.preventDefault();
return false;
},
dragOver: function(event) {
event.preventDefault();
return false;
},
drop: function(event) {
event.preventDefault();
// Extract the transferred data
var rawData = event.dataTransfer.getData('application/json');
// Create a new Ember object from the data
var item = App.Todo.create(JSON.parse(rawData));
this.get('controller').send('add', item);
return false;
}
});
Check out JS Bin for the complete code.
Thanks in advance for your help. Very much appreciated.
This is maybe not the full solution to your problem, but it satisfies the need to use the action helper instead of the itemView. Here is your modified jsbin http://jsbin.com/ibufeh/15/edit?html,javascript,live, the drop event fires and is catched at the ApplicationRoute level, from where you can then redirect your function call to the appropriate controller, have a look! it's not working correctly but it solves part of your problem - using an action helper. You need still to figure out from which list the item originated, but this will be easy I guess.
hope it helps