Google Maps Use Case has a JS error in Firefox - javascript

I have a FF error about the info window in GM. Here is the source code:
var lats;
var longs;
var k;
function initialize() {
//parentArray is an object where the elements of the parent page are stored
var parentArray = window.parent.params;
lats = parentArray["lat"].replace(/^\|+|\|+$/g, '').split("|");
longs = parentArray["long"].replace(/^\|+|\|+$/g, '').split("|");
k = parentArray["keys"].replace(/^\|+|\|+$/g, '').split("|");
var myLatlng = new google.maps.LatLng(parseFloat(lats[0]), parseFloat(longs[0]));
var myOptions = {
zoom: 20,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
//contentString is built based on the array passed by the parent page
for (var i = 0; i < lats.length; i++) {
var contentString = '<div id="content"' + i + '><b>' + k[i] + '</b>';
for (var f in parentArray)
if ((f !== "long") && (f !== "lat") && (f !== "keys") && (parentArray[f].substring(0, 1) !== "<")) {
contentString += '<br />' + f + ': ' + parentArray[f];
}
contentString += '<br /></div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(lats[i]), parseFloat(longs[i])),
map: map,
title: 'Position'
});
createInfoWindow(marker, contentString);
function createInfoWindow(m, content) {
google.maps.event.addListener(m, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, m);
});
}
}
}
params is an array with information and k is an array of keys for the markers on the google map. Does anybody know why do I have a FF error for this code?
Sample Data For params:
params['foo']: bar
params['keys']: "Start Position|End Position"
params['lat']: "12.5323703|13.5323703"
params['long']: "14.5786987|15.5786987"
EDIT:
The Error is: createInfoWindow is not defined
Thanks in advance,
Lajos Arpad.

You are defining your method inside a loop (this is bad on its own..) and you call the method before you define it ..
just moving the call below the definition fixes the issue..
function createInfoWindow(m, content) {
google.maps.event.addListener(m, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, m);
});
}
createInfoWindow(marker, contentString);
Demo at http://jsfiddle.net/gaby/gdLVd/
But you should really move the definition of the createInfoWindow method somewhere else..
Better demo at http://jsfiddle.net/gaby/gdLVd/1/

Related

How to assign values to javascript object through angularjs ng-click function

In the below code I am trying to set some values for google map's lat long, when I call the change function which is bound to ng-click directive, the page doesn't load, but without change() func everything loads pretty well. I might be missing some core concepts of angular that is because I have started working on it just 10 days before, kindly correct me here and if someone can suggest me another way to change my lat long with button click, I will be really thankful for that suggestion.
app.controller('MapCtrl', function ($scope){
// $scope.change=function(){
$scope.Latitude="23.200000";
$scope.Longitude="79.225487";
$scope.assignLat=function () {
var lati= $scope.Latitude;
return lati;
}
$scope.assignLong=function () {
var longi= $scope.Longitude;
return longi;
}
console.log($scope.assignLat());
console.log($scope.assignLong());
// }
var cities = [{
city : 'India',
desc : 'This is the best country in the world!',
lat : $scope.assignLat(),
long : $scope.assignLong()
}];
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(25,80),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
var createMarker = function (info){
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.long),
title: info.city
});
marker.content = '<div class="infoWindowContent">' + info.desc + '</div>';
google.maps.event.addListener(marker, 'click', function(){
infoWindow.setContent('<h2>' + marker.title + '</h2>' + marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
for (i = 0; i < cities.length; i++){
createMarker(cities[i]);
}
$scope.openInfoWindow = function(e, selectedMarker){
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
});

Google Maps API V3, Marker InfoWindows not opening

I am building a GoogleMap with multiple markers with infowindows attached. I have tried to build this into a re-usable Javascript Class using prototypes but my infowindows will not open (the markers show up fine).
If I test console.log within the click event listener it triggers, but the infowindows themselves refuse to open.
Markers.json is just a JSON object which returns a list of data to be looped through.
JS Fiddle
I am initiating the map using:
$(document).ready(function(){
var customMap = new CustomMap('mapitems');
customMap.init();
customMap.setMarkers();
});
My Javascript:
function CustomMap(mapId, defaultLat, defaultLng, defaultZoom)
{
this.map = null;
this.markerBounds = null;
this.$mapContainer = document.getElementById(mapId);
this.defaultLat = (defaultLat ? defaultLat : '-36.848460');
this.defaultLng = (defaultLng ? defaultLng : '174.763332');
this.defaultZoom = (defaultZoom ? defaultZoom : 15);
}
CustomMap.prototype.init = function() {
var position = new google.maps.LatLng(this.defaultLat, this.defaultLng);
this.map = new google.maps.Map(this.$mapContainer, {
scrollwheel: true,
mapTypeId: 'roadmap',
zoom: this.defaultZoom,
position: position
});
this.markerBounds = new google.maps.LatLngBounds();
};
CustomMap.prototype.setMarkers = function() {
var that = this;
$.get('/locations.json', null, function(locations) {
for (var i = 0; i < locations.length; i++) {
that.processMarker(locations[i]);
}
that.map.fitBounds(that.markerBounds);
}, 'json');
};
CustomMap.prototype.processMarker = function(data) {
if (data.lat && data.lng) {
var position = new google.maps.LatLng(data.lat, data.lng);
this.markerBounds.extend(position);
var marker = this.getMarker(position);
this.setInfoWindow(marker, data);
}
};
CustomMap.prototype.getMarker = function(position) {
return new google.maps.Marker({
map: this.map,
draggable:false,
position: position
});
};
CustomMap.prototype.setInfoWindow = function(marker, data) {
var that = this;
marker.infoWindow = new google.maps.InfoWindow({
content: that.buildInfoHtml(data)
});
google.maps.event.addListener(marker, 'click', function() {
marker.infoWindow.open(that.map, marker);
});
};
CustomMap.prototype.buildInfoHtml = function(data) {
var html = '';
html += '<strong>' + data.title + '</strong><br>';
if (data.address.length > 0)
html += data.address + '<br>';
if (data.freephone.length > 0)
html += 'Freephone: ' + data.freephone + '<br>';
if (data.depotPhone.length > 0)
html += 'Depot Phone: ' + data.depotPhone + '<br>';
if (data.hours.length > 0)
html += 'Depot Hours: ' + data.hours + '<br>';
return html;
};

JavaScript multidimensional array cannot access as array, only as string

I am trying to put multiple markers on a Google map. I have JS that builds an array and passes it to the Google function that handles markers.
Problem is, when I try to access the supposed array, I just get the first character as if it's a string.
$(document).ready(function () {
// initialize map to center on florida.
initializeGMap();
var locations = [];
#foreach (var item in Model)
{
<text>
locations.push(#Html.Raw(Json.Encode("'" + item.Name + "'," + item.Location.Latitude + "," + item.Location.Longitude + "")));
</text>
}
addMarker(locations);
});
I've tried several (read: 20+) variations of this including JSON.stringify it before sending, after sending, etc. Here's the function it gets passed too:
function addMarker(locations) {
var locations = JSON.stringify(locations);
alert(locations + '\n' + locations[0][0] + '\n' + locations[0][1]);
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
alert("done");
}
When it gets to the line with 'locations[x][x]' all I ever get back in '[' which is the first character of the JSON string. It's not being treated at an array.
What am I missing?
I solved it via:
$(document).ready(function () {
// initialize map to center on florida.
initializeGMap();
// serialize model locations
var locationsToPass = #Html.Raw(Json.Encode(Model.Select(x => new { x.Name, x.Location.Latitude, x.Location.Longitude })));
addMarker(locationsToPass);
});
and in the receiving function:
function addMarker(locations) {
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].Latitude, locations[i].Longitude),
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i].Name);
infowindow.open(map, marker);
}
})(marker, i));
}
}
The key to troubleshooting was using this to detect if I was passing an array or not:
variable.constructor === Array
which I got here.

How can I create Google Map markers in a loop like "Marker1", "Marker2"

Sorry for that newbie's question, but I didn't found any idea for that issue...
I would to create 4 markers (or more, but here it's 4) on a Google Map. I get the informations with a GET ajax request, responding with JSON. I'm able to create those markers, but I have a problem with the information window for each marker.
here the code I tried :
function readDevices(output){
// Get an array for the 4 devices with guid 42421 42422 42423 and 42424
var arrayOfDevices = new Array();
$.each(output.data, function(key, value){
$.each(value, function(deviceKey, deviceValue){
if(deviceKey == 'guid' && deviceValue >= 42421 && deviceValue <= 42424){
arrayOfDevices.push(value); // add the entire object in the tab
}
});
});
for(var i = 0; i < arrayOfDevices.length; i++){
var guid = arrayOfDevices[i]["guid"];
var latitude = arrayOfDevices[i]["latitude"];
var longitude = arrayOfDevices[i]["longitude"];
var name = arrayOfDevices[i]["name"];
var coord = new google.maps.LatLng(latitude, longitude);
var contentString = '<div id="content">'+
'<form method="get" action="manual" id="form-new">'+
'<button type="submit" id="new-button" name="'+guid+'" class="btn new-btn">Manual</button>'+
'</form>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: coord,
title: name
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
}
This code put 4 markers, at the right place. But when I click on one of those markers, the "pop up window" appears near from the LAST marker that I have created. I would like to set information window for each marker.
I can't do something like :
var marker+i = new google.maps.Marker();
... But maybe there is tips for do some stuff like that ?
I hope it was clear ^^'
Thanks for helping, guys ! :-)
CORRECT CODE AFTER KhorneHoly answer ! Thanks to him.
function addMarker(markerData, map){
var contentString = '<div id="content">'+
'<form method="get" action="manual" id="form-new">'+
'<button type="submit" id="new-button" name="'+markerData["guid"]+'" class="btn new-btn">Manual</button>'+
'</form>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var LatLng = new google.maps.LatLng(markerData["latitude"], markerData["longitude"]);
var marker = new google.maps.Marker({
position: LatLng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
function readDevices(output){
var arrayOfDevices = new Array();
var markers = new Array();
$.each(output.data, function(key, value){
$.each(value, function(deviceKey, deviceValue){
if(deviceKey == 'guid' && deviceValue >= 42421 && deviceValue <= 42424){
arrayOfDevices.push(value);
}
});
});
for(var i = 0; i < arrayOfDevices.length; i++){
var guid = arrayOfDevices[i]["guid"];
var latitude = arrayOfDevices[i]["latitude"];
var longitude = arrayOfDevices[i]["longitude"];
var name = arrayOfDevices[i]["name"];
var coord = new google.maps.LatLng(latitude, longitude);
markers.push(addMarker(arrayOfDevices[i], map));
}
}
What you want to do is not possible because you can't generate variables like this. But what you can do is to generate an array you fill with the markers in an for loop like this:
var markers = new Array();
for (var i = 0; i < ArrayWithYourResultYouWantGenerateTheMarkersFrom.length; ++i) {
markers.push(addMarker(ArrayWithYourResultYouWantGenerateTheMarkersFrom.[i], map));
}
public function addMarker(markerData, map){
var LatLng = new google.maps.LatLng(markerData.lat, markerData.lon);
var marker = new google.maps.Marker({
position: LatLng,
map: map,
}

Different results in Google Places API and Google Maps

I'm using the Google Places JavaScript API for a desktop application. However, the search results returned by the API aren't the same as the ones I get in maps.google.com. For instance, if I search for "Antique Hostel", I get many results (almost all of them are kinda random) whereas on Google Maps I get the correct (single) result.
Is the quality of the search isn't the same in the API and the service?
Here is my code
function initialize() {
// map setup
var mapOptions = {
center: new google.maps.LatLng(52.519171, 13.406091199999992),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
$map = document.getElementById('mapCanvas'),
map = new google.maps.Map($map, mapOptions),
input = document.getElementById('searchInput'),
autocomplete = new google.maps.places.Autocomplete(input),
service = new google.maps.places.PlacesService(map),
$ajaxSearchInput = $(input),
markers = [];
autocomplete.bindTo('bounds', map);
$ajaxSearchInput.keydown(function(e) {
if (e.keyCode === 13) {
var request = {
query: $(this).val(),
radius: '500',
location: map.getCenter()
}
service.textSearch(request, searchCallBack);
}
});
searchCallBack = function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var bounds = new google.maps.LatLngBounds();
console.log(results);
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
for (var i = 0; i < results.length; i++) {
var place = results[i];
createMarker(results[i], bounds);
}
map.fitBounds(bounds);
}
}
createMarker = function(place, bounds) {
var marker = new google.maps.Marker({
map: map,
title: place.name,
position: place.geometry.location
});
// event listener to show the InfoWindow.
(function(marker, place) {
google.maps.event.addListener(marker, 'click', function() {
var content = '<h3>' + place.name + '</h3> ' + place.formatted_address + '<br>',
infowindow = new google.maps.InfoWindow({
content: ''
});
if (place.rating) {
content += '<p> <b>Rating</b>: ' + place.rating + '</p>';
}
if (place.types) {
content += '<p> <b>Tags</b>: ';
for (var j = 0, tag; tag = place.types[j]; j++) {
content += tag + ', '
}
content += '</p>';
}
infowindow.content = content;
infowindow.open(map, marker);
});
})(marker, place);
markers.push(marker);
bounds.extend(place.geometry.location);
}
}
google.maps.event.addDomListener(window, 'load', initialize);

Categories