Uncaught ReferenceError: infowindow is not defined #googleMaps API - javascript

I'm trying to integrate the Google maps API to my page. I use a code that extract the locations from JSON and saves the location in an array, then return the place-data of each location. Everything went well except I can't activate the infowindow function when clicking on marker on the map. This is the error that appears when clicking:
var map; // declares a global map variable
/*
Start here! initializeMap() is called when page is loaded.
*/
function initializeMap() {
var locations;
var mapOptions = {
disableDefaultUI: true
};
/*
For the map to be displayed, the googleMap var must be
appended to #mapDiv in resumeBuilder.js.
*/
map = new google.maps.Map(document.querySelector('#map'), mapOptions);
/*
locationFinder() returns an array of every location string from the JSONs
written for bio, education, and work.
*/
function locationFinder() {
// initializes an empty array
var locations = [];
// adds the single location property from bio to the locations array
locations.push(bio.contacts.location);
// iterates through school locations and appends each location to
// the locations array. Note that forEach is used for array iteration
// as described in the Udacity FEND Style Guide:
// https://udacity.github.io/frontend-nanodegree-styleguide/javascript.html#for-in-loop
education.schools.forEach(function(school){
locations.push(school.location);
});
// iterates through work locations and appends each location to
// the locations array. Note that forEach is used for array iteration
// as described in the Udacity FEND Style Guide:
// https://udacity.github.io/frontend-nanodegree-styleguide/javascript.html#for-in-loop
work.jobs.forEach(function(job){
locations.push(job.location);
});
return locations;
}
/*
createMapMarker(placeData) reads Google Places search results to create map pins.
placeData is the object returned from search results containing information
about a single location.
*/
function createMapMarker(placeData) {
// The next lines save location data from the search result object to local variables
var lat = placeData.geometry.location.lat(); // latitude from the place service
var lng = placeData.geometry.location.lng(); // longitude from the place service
var name = placeData.formatted_address; // name of the place from the place service
var bounds = window.mapBounds; // current boundaries of the map window
// infoWindows are the little helper windows that open when you click
// or hover over a pin on a map. They usually contain more information
// about a location.
var infoWindow = new google.maps.InfoWindow({
content: name
});
// marker is an object with additional data about the pin for a single location
var marker = new google.maps.Marker({
map: map,
position: placeData.geometry.location,
title: name
});
// hmmmm, I wonder what this is about...
marker.addListener('click', function() {
// your code goes here!
infowindow.open(map, marker);
});
// this is where the pin actually gets added to the map.
// bounds.extend() takes in a map location object
bounds.extend(new google.maps.LatLng(lat, lng));
// fit the map to the new marker
map.fitBounds(bounds);
// center the map
map.setCenter(bounds.getCenter());
}
/*
callback(results, status) makes sure the search returned results for a location.
If so, it creates a new map marker for that location.
*/
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
createMapMarker(results[0]);
}
}
/*
pinPoster(locations) takes in the array of locations created by locationFinder()
and fires off Google place searches for each location
*/
function pinPoster(locations) {
// creates a Google place search service object. PlacesService does the work of
// actually searching for location data.
var service = new google.maps.places.PlacesService(map);
// Iterates through the array of locations, creates a search object for each location
locations.forEach(function(place){
// the search request object
var request = {
query: place
};
// Actually searches the Google Maps API for location data and runs the callback
// function with the search results after each search.
service.textSearch(request, callback);
});
}
// Sets the boundaries of the map based on pin locations
window.mapBounds = new google.maps.LatLngBounds();
// locations is an array of location strings returned from locationFinder()
locations = locationFinder();
// pinPoster(locations) creates pins on the map for each location in
// the locations array
pinPoster(locations);
}
/*
Uncomment the code below when you're ready to implement a Google Map!
*/
// Calls the initializeMap() function when the page loads
window.addEventListener('load', initializeMap);
// Vanilla JS way to listen for resizing of the window
// and adjust map bounds
window.addEventListener('resize', function(e) {
// Make sure the map bounds get updated on page resize
map.fitBounds(mapBounds);
});

You are trying to create an infoWindow object here:
// infoWindows are the little helper windows that open when you click
// or hover over a pin on a map. They usually contain more information
// about a location.
var infoWindow = new google.maps.InfoWindow({
content: name
});
and then work with it (show message after marker click)
// hmmmm, I wonder what this is about...
marker.addListener('click', function() {
// your code goes here!
infowindow.open(map, marker);
});
But look at your variables attentively:
infoWindow !== infowindow (letter W)
browser doesn't know, what infowindow is, and falls with an error.
Read more about variables naming in JS here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Declarations

I came across this question while trying to debug some code that I had copied from the Udacity tutorial (Getting Started with the APIs) that Hasam was drawing from. My code, as copied from the video itself, lacked some key lines, and wouldn't run correctly. The tutorial's 'resources' didn't have a copy of the code. I eventually found a good copy of the code on Github: https://github.com/udacity/ud864. As I wrote this answer, I found the same link tucked away on the bottom of some of the Udacity tutorial pages themselves.

Related

Allow user to add marker to google maps only at specific zoom level

I have a website where users will be allowed to add their properties on google map using markers/pins, I want to (Obligate) the user to go to the max allowed zoom level to be able to set the pin/marker, so as to have a specific exact location of the property.
You can use the getZoom() method on the Map object and check what the current zoom level is before allowing a new Marker to be created.
Here's a simple sample JSBin adapted from the Remove Markers sample from Google's documentation. The pertinent code:
// Adds a marker to the map and push to the array.
function addMarker(location) {
if (map.getZoom() < 17) {
alert('please zoom in closer to add a new marker');
} else {
var marker = new google.maps.Marker({
position: location,
map: map
});
markers.push(marker);
}
}

Show users submited address in google map infowindow when clicked (Wordpress and ACF plugin)

guys I hope you can help me out with this issue. Bassically I'm trying to achive next goal:
Users fills out form (Buddyform + ACF plugin)-> Automatically post are being created from users submited form information
But there is a problem with that since one if the forms fields is Google Map field (created in ACF).
Transaction from form to post is very nice. But for some reason information about selected address is missing. Meaning that you can see marker on map and you can move map, but you can't see what is exact address.
The idea was to include address in infowindow which would open onclick. But so far I understood just how to include manually written text (content : "text here"). But I want that in infowindow would appear address from Buddyform that user submited.
Is there a way to do so?
You can see my testing here
Since am not really good with coding I use plugins for custom fields creation (ACF plugin) and in order to show custom fields in post (wpView plugin)
OK from what I can see from the documentation link in your comments. You have to add the code from the Helpers section into your page template.
In the add_marker($marker, map) method you can make another api call to get a human readable address of the marker location.
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'),
$marker.attr('data-lng') ),
formatAddress = "";
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map
});
Using the latLng variable to make request to the Geocoding service in order to get a formatted address from the variable's lat/lang coordinates.
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'location': latLng}, function(results, status)
{
if (status == 'OK') {
formatAddress = results[0].formatted_address;
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
// add to array
map.markers.push( marker );
Then you when add the infowindow you can put the formatted address as it's body content.
// if marker contains HTML, add it to an infoWindow
if( $marker.html() )
{
// create info window
var infowindow = new google.maps.InfoWindow({
content : formatAddress
});
// show info window when marker is clicked
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}

Opening a second InfoWindow in Google Maps API v3

I'm implementing a Maps interface for a database of music venues and events and have run into an interesting issue. I have a series of HTML elements with onclick calls to a certain Javascript function. The calls run correctly and the javascript function runs correctly the first time (all the information is passed in correctly and my debug alerts display it correctly), and the infoWindow displays. The second time I click on one of these divs, the first one closes correctly, the final alert in the code below fires with the correct information, but the new InfoWindow does not pop up.
Map setup code:
function mapsInitialize() {
var mapOptions = {
center: new google.maps.LatLng(42.4439614, -76.5018807),
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapSection"), mapOptions);
google.maps.event.trigger(map, 'resize');
for(var x = 0; x < markers.length; x++){
var tempOptions = {
position: markers[x].position,
title: markers[x].name,
map: map
}
markerObjects[markers[x].title] = new google.maps.Marker(tempOptions);
}
}
Function called onclick from the divs:
function generateInfoWindow(despacedName, despacedTitle, eventTitle, url, date, time){
if(curInfoWindow){
alert("closing " + curInfoWindow.getContent());
curInfoWindow.close();
curInfoWindow = null;
}
curInfoWindow = new google.maps.InfoWindow(options = {size: new google.maps.Size(150,50)});
curInfoWindow.setContent("<a class=\"eventLink\" href=\""+url+"\">"+eventTitle+"</a><br><br>"+markerObjects[despacedName].title+"<br>"+date+" at "+time);
curInfoWindow.open(map, markerObjects[despacedName]);
alert(despacedName+" is "+markerObjects[despacedName]);
}
I can guarantee that the markers[] array is fed correctly.
I have tried, among other things...
Creating an array to hold the infoWindows instead of using one curInfoWindow variable
Not having anything in the array automatically close like the beginning of the generateInfoWindow() function does
Creating the info windows automatically in the mapsInitialize() function
Most of the results on Google when searching for solutions brought me information about event listeners on the map - is that the only way to fire an event like this, or is what I'm trying to do valid?
If any other code examples are needed, let me know. Thanks for any suggestions!
According to Google Maps API:
InfoWindows may be attached to either Marker objects (in which case
their position is based on the marker's location) or on the map itself
at a specified LatLng. If you only want one info window to display at
a time (as is the behavior on Google Maps), you need only create one
info window, which you can reassign to different locations or markers
upon map events (such as user clicks). Unlike behavior in V2 of the
Google Maps API, however, a map may now display multiple InfoWindow
objects if you so choose.
Maybe this would work:
function generateInfoWindow(despacedName, despacedTitle, eventTitle, url, date, time){
if(!curInfoWindow){
curInfoWindow = new google.maps.InfoWindow({maxWidth:150});
}
curInfoWindow.setContent("<a class=\"eventLink\" href=\""+url+"\">"+eventTitle+"</a><br><br>"+markerObjects[despacedName].title+"<br>"+date+" at "+time);
curInfoWindow.open(map, markerObjects[despacedName]);
alert(despacedName+" is "+markerObjects[despacedName]);
}
According to the specs, this should move the existing curInfoWindow to a new marker and update the content.
Note: this code is invalid
new google.maps.InfoWindow(options = {size: new google.maps.Size(150,50)})
There is no size attribute. The best you can do is
new google.maps.InfoWindow({maxWidth:150})
More about InfoWindow API

JS Function undefined when it is clearly a prototype of the object I am using

I am using GoogleMaps JS API V3 with ClusterMarker. So far so good, I have a working map with customised clusters.
I decided I needed a method to open the infoWindow with some information of the clicked cluster, including some anchored links.
I did some searching on SO and Google and came up with something along these lines from this StackOverflow answer.
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerCluster, 'clusterclick', function (clickedCluster) {
console.log(clickedCluster);
var center = clickedCluster.getCenter();
var latLng = new google.maps.LatLng(center);
// infowindow.setContent("Info Window");
// infowindow.setPosition(latLng);
// infowindow.open(map);
});
In the console.log(clickedCluster) I'm given a Cluster object that has 6 methods, and a load of properties. One of these functions is getCenter() that returns the 'Center of the cluster icon that has been clicked'.
When I uncomment this line: var center = clickedCluster.getCenter(); I get an error saying that getCenter() is not a function.
Can anyone help me shed some light on what I'm doing wrong here please?
Thanks in advance
So the solution to the problem turned out to be that clickedCluster was returned as an array. The below works great.
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerCluster, 'clusterclick', function (clickedCluster) {
var center = clickedCluster[0].getCenter();
var latLng = new google.maps.LatLng(center.lat(),center.lng());
infoWindow.setContent(getDailyDeals(center.lat(),center.lng()));
infoWindow.setPosition(latLng);
infoWindow.open(map);
});

Google maps - jQuery - Php integration check

I am constructing a pretty massive website that is WP powered , but uses Google maps as a main interface .
I have a page on the admin side, where I want to be bale to select a location by dragging a marker , and then save this data to MySQL (via Php/wp functions)
Problem is - as much as my WP and PHP foundations are pretty solid , my JS or Jquery are quite basic, not to say shaky .
I have "hacked" together a code from reading the Google maps API, tutoials, and examples -
It produces the map correctly, and also the marker to be dragged , and then it passes the value of [Lat,Lng] to a TXT input via jQuery - which then is saved to the DB.
Everything works fine - except for one issue :
when I edit or save the data - the next time I will open this "post" - there is no marker ,and I need to make a new one and save again .
when I tried to get the Values of the input field with simple
var LatPoint = jQuery('[name=LatTxt]').val()
and
placeMarker(new google.maps.LatLng(LatPoint,LngPoint));
the map failed to generate at all.
The second is that the drag marker function does not update the input.
the third (and not less important) is that I KNOW that the code is horrible, and I am SURE there is a better way to achieve this - and whis whole website purpose is also for me to LEARN - I would like someone to revise the code and advise on how to optimize it ..
this is the code I have up to now ..
var map;
var markersArray = [];// to be used later to clear overlay array
jQuery(document).ready(function(){
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_2k"), myOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
var marker;
//Function to extract longitude
function placeMarker(location) {
if ( marker ) {
marker.setPosition(location);
} else {
marker = new google.maps.Marker({
position: location,
draggable: true,
title: 'Drag me',
map: map
});
markersArray.push(marker); // to be used later to clear overlay array
}
}
// Removes the overlays from the map, but keeps them in the array
function clearOverlays() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
}
}
//Jquery update HTML input boxes
function updatelonlat() {
jQuery('#LatTxt').val(marker.getPosition().lat());
jQuery('#LonTxt').val(marker.getPosition().lng());
}
// add event click
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
updatelonlat();
//var lat = parseFloat(document.getElementById('LatTxt').value); - somehow not working
});
//google.maps.event.addListener(marker, 'dragend', function(event) {
//document.getElementById("#LatTxt").value = event.latLng.lat(); - somehow not working
map.setCenter(location);
});
Any help would be greatly appreciated ..
EDIT I
I have set up a JSFIDDLE : http://jsfiddle.net/obmerk99/fSj9F/1/
Obviously I can not simulate the PHP function - but it is not needed .
What I want is when the page loads /refresh / save - it will start with a CENTER and a MARKER with vaalues from the input box...
Also - I just now noticed that the drag action is also not updating , I do not know if it is jsfiddle - or my function ...
I've fixed your code in JSFiddle: http://jsfiddle.net/fSj9F/2/
The problems was:
1) You didn't read the values of your inputs before creating the map, and setting the center.
2) You tried to use map.setCenter(location), but the location variable wasn't set
3) You never called your placeMarker function, so the marker was never placed, before the user clicked the map
4) Even though you didn't use the clearOverlays function, I replaced the for..in loop with a regular for. This way you don't iterate the properties of the array (which isn't just the elements, but also the methods of the Array object), but instead you only iterate over the elements contained in the array.
Notice that your code might've been easier to read if you'd declared your functions out of the "ready" function, and if you didn't use global variables such as marker.

Categories

Resources