I have this google map which is working, I want to add a button on infowindow which somehow is not working. Though the function is defined but still throw error
http://jsfiddle.net/mpgxn53q/
<div id="apptMap"></div>
//the js code
<script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
var locations = [["158845-001 - Adas Israel Congregation",38.9369545,-77.0575097,1],["163888-137 - Construction LLC",43.1765812,-84.6986701,2.0],["163888-155 - Construction LLC",43.1765812,-84.6986701,3.0],["167176-007 - GLDB MTM10 GLR016",42.4894512,-95.5449508,4.0],["167195-003 - 91622 DB A4",42.8275053,-84.5717997,5.0],["167195-002 - 91622 DB A4",42.8275053,-84.5717997,6.0],["167176-005 - GLDB MTM10 GLR016",42.0023,-93.6110955,7.0],["167176-004 - GLDB MTM10 GLR016",42.0023,-93.6110955,8.0]];
var map;
var markers = [];
function init(){
map = new google.maps.Map(document.getElementById('apptMap'), {
zoom: 10,
center: new google.maps.LatLng(42.0023,-93.6110955),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var num_markers = locations.length;
for (var i = 0; i < num_markers; i++) {
markers[i] = new google.maps.Marker({
position: {lat:locations[i][1], lng:locations[i][2]},
map: map,
html: locations[i][0],
id: i,
});
google.maps.event.addListener(markers[i], 'click', function(){
var infowindow = new google.maps.InfoWindow({
id: this.id,
content:this.html +'<button onclick="mapsZoomMarker('+i+')">Click me</button>',
position:this.getPosition()
});
google.maps.event.addListenerOnce(infowindow, 'closeclick', function(){
markers[this.id].setVisible(true);
});
this.setVisible(false);
infowindow.open(map);
});
}
}
function mapsZoomMarker(wnMarker){
map.setCenter(markers[wnMarker].getPosition());
map.setZoom(15);
}
init();
There is a problem with scopes, and that's because of that how you wrote your script. I am not going to rewrite your script, but I will give you solution for your exact situation.
You need to define your function mapsZoomMarker in global scope (window object) like this:
window.mapsZoomMarker = function (wnMarker){
map.setCenter(markers[wnMarker].getPosition());
map.setZoom(15);
}
And there is also a mistake, in the function which is called when the marker is clicked. When you assign the html for the popup like this
content: this.html +'<button onclick="mapsZoomMarker('+i+')">Click me</button>'
the i variable is already set to 8, so instead of that just use this.id like this:
content: this.html +'<button onclick="mapsZoomMarker('+this.id+')">Click me</button>'
And this is the updated fiddle http://jsfiddle.net/rn27f05v/
I will propose a solution that I think is best for what you want. Instead call function inside var infowindow, you can only define a variable to put content your want.
You can change you var infowindow to:
var infowindow = new google.maps.InfoWindow({
id: this.id,
content: content, //here the variable that call your content
position:this.getPosition()
});
So... above your google.maps.event.addListener(markers[i], 'click', function(){... you can add:
var content = '<button onclick="mapsZoomMarker('+i+')">Click me</button>';
This way the click action will work.
Hope this tip help you.
Related
I am trying to implement a rating system inside the infowindow on Google Maps API version 3.
I tried both Rateit and Raty and I coudn't make neither of them work.
I tried this code here and it doesn't work for me:
function initialize() {
var mapOptions = {
zoom: 5,
center: new google.maps.LatLng(2, 2),
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions),
locations = [
[null, 1, 1, 'title#1', null, null, 1.3, 'foo'],
[null, 2, 2, 'title#2', null, null, 3.7, 'bar'],
[null, 3, 3, 'title#3', null, null, 4.3, 'boofar']
],
infowindow = new google.maps.InfoWindow(),
i;
//use the domready-event of the infowindow to execute $.raty
google.maps.event.addListener(infowindow, 'domready', function() {
$(this.getContent()).find('.stars').raty({
half: true,
score: function() {
return $(this).attr('data-score');
},
readOnly: true,
path: 'https://raw.githubusercontent.com/wbotelhos/raty/master/demo/images/'
});
});
for (i = 0; i < locations.length; i++) {
(function(location) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(location[1], location[2]),
title: location[3],
map: map,
info: $('<div/>')
//the rating
.append($('<div class="stars"></div>').attr('data-score', location[6]))
//review-link
.append($('' + locations[i][7] + ' reviews'))
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(this.info[0]);
infowindow.open(map, this);
});
}(locations[i]))
}
}
google.maps.event.addDomListener(window, 'load', initialize);
Here is my code and what I have done so far.
Scripts:
<!-- Load libraries -->
<script src="js/jquery-1.12.1.min.js"></script>
<script src="js/jquery.raty.js"></script>
<!-- Google Maps API tag -->
<script src="https://maps.googleapis.com/maps/api/js?v=3">
</script>
<script type="text/javascript">
window.addEventListener("load",function() {
// Set a timeout...
setTimeout(function(){
// Hide the address bar!
window.scrollTo(0, 1);
}, 0);
});
$('.search-box,.menu' ).hide();
$('.options li:first-child').click(function(){
$(this).toggleClass('active');
$('.search-box').toggle();
$('.menu').hide();
$('.options li:last-child').removeClass('active');
});
$('.options li:last-child').click(function(){
$(this).toggleClass('active');
$('.menu').toggle();
$('.search-box').hide();
$('.options li:first-child').removeClass('active');
});
$('.content').click(function(){
$('.search-box,.menu' ).hide();
$('.options li:last-child, .options li:first-child').removeClass('active');
});
</script>
<!-- Google Maps Script -->
<script type="text/javascript">
function initMap() {
// Create a map object and specify the DOM element for display.
var zoomlevel = 10;
var abudhabi = {lat:24.373368, lng:54.488754};
var map = new google.maps.Map(document.getElementById('map'), {
center: abudhabi,
scrollwheel: false,
zoom: zoomlevel
});
// Load up markers with their labels and infos.
//Test variables:
var locations = [
['McGettigan \'s Irish Pub',24.438533,54.572991,2],
['Cooper\'s',24.4238,54.473619,3]
];
var infowindow = new google.maps.InfoWindow();
//on infowindow load -> read data and display stars
google.maps.event.addListener(infowindow, 'domready', function() {
$(this.getContent()).find('.stars').raty({
score: function() {
return $(this).attr('data-score'); // THIS DOESN'T RETURN ANY VALUE...
},
readOnly: true,
path: 'images/' //this is my path for the images, they are fine...
});
});
for (var i=0; i<locations.length; i++){
(function(location){
var marker = new google.maps.Marker({
position: new google.maps.LatLng(location[1], location[2]),
title: location[0],
map: map,
info: $('<div/>')
.append($('<div class="stars"></div>').attr('data-score', location[3]))
});
// Add event listener on marker -> open info
google.maps.event.addListener(marker, 'click',function(){
infowindow.setContent(this.info[0]);
infowindow.open(map,this);
});
})(locations[i])
}
}
google.maps.event.addDomListener(window,'load',initMap);
</script>
The raty.js is returning (line 1 error):
Error: Invalid selector!
Really appreciate the help, I am new in javascript and jquery. I tried hard but I coudn't figured out the reason why is not working.
Thank you in advance.
Found my mistake: Rateit script was working before I insert the div tag for it to read. I missed a basic concept here. Solution was like this:
var infowindow = new google.maps.InfoWindow();
//on infowindow load -> read data and display stars
google.maps.event.addListener(infowindow, 'domready', function() {
$("#info").rateit(); //HERE IS THE TRICK (CALL RATEIT AGAIN)
});
for (var i=0; i<locations.length; i++){
(function(location){
var marker = new google.maps.Marker({
position: new google.maps.LatLng(location[1], location[2]),
title: location[0],
map: map,
});
// Add event listener on marker -> open info
google.maps.event.addListener(marker, 'click',function(){
var content = '<div class="rateit"'+
' data-rateit-value="'+ location[3] +
'" data-rateit-ispreset="true" data-rateit-readonly="true"'+
' id="info"></div>';
infowindow.open(map,this);
infowindow.setContent(content);
});
})(locations[i])
}
In any case, I still couldn't make raty work. Everytime I called it inside 'domready' event tons of stars appeared and score function never returned the attribute 'data-score'..
Anyway I found another way so it's fine for now.
Thanks.
I'm working on a web app that includes google map and a bunch of markers.
This morning I had working map+markers from db (but I used only one table with data).
ss this morning:
Now I'm trying to put marker custom icons and info windows to get something like this (this was made without laravel, only php).
This is my code:
#extends('layouts.app')
#section('content')
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function load() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 45.327168, lng: 14.442902},
zoom: 13
});
var infoWindow = new google.maps.InfoWindow;
#foreach($markers as $marker)
var sadrzaj = {{$marker->nazivMarkera}};
var adresa = {{$marker->adresa}};
var grad = {{$marker->nazivGrada}};
var postanskibroj = {{$marker->postanski_broj}};
var zupanija = {{$marker->nazivZupanije}};
var html = "<b>" + sadrzaj + "</b> <br/>" + adresa +",<br/>"+postanskibroj+" "+grad+",<br/>"+zupanija;
var lat = {{$marker->lat}};
var lng = {{$marker->lng}};
var image = {{$marker->slika}};
var markerLatlng = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
var mark = new google.maps.Marker({
map: map,
position: markerLatlng,
icon: image
});
bindInfoWindow(mark, map, infoWindow, html);
#endforeach
}
function bindInfoWindow(mark, map, infoWindow, html){
google.maps.event.addListener(marker, 'click', function(){
infoWindow.setContent(html);
infowWindow.open(map, mark);
});
}
function doNothing(){}
//]]>
</script>
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Dobro došli!</div>
<div class="panel-body">
<!-- Moj kod -->
<div id="map"></div>
<!-- DO TU -->
</div>
</div>
</div>
</div>
</div>
#endsection
When I inspect the page I can see that my array with data is filled and I have all the data from db.
Can someone help me and explain to me where is the problem? Why when I remove functions for markers, and set only map init, I get map view with no problem, and now I don't even get the map.
Now:
It looks like load() is not getting called anywhere.
Also I noticed in your screen shots, the variables which have been echoed in by laravel don't have quotes around them.
I would leave laravel(blade) out of the javascript. Currently, your foreach loop will dump heaps of javascript code which will be overriding and re-declaring variables. This is generally messy, and considered bad practice.
I would also make map a global variable, incase you want to manipulate it later.
Try this:
var map;
var markers = {!! json_encode($markers) !!}; //this should dump a javascript array object which does not need any extra interperting.
var marks = []; //just incase you want to be able to manipulate this later
function load() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 45.327168, lng: 14.442902},
zoom: 13
});
for(var i = 0; i < markers.length; i++){
marks[i] = addMarker(markers[i]);
}
}
function addMarker(marker){
var sadrzaj = marker.nazivMarkera};
var adresa = marker.adresa;
var grad = marker.nazivGrada;
var postanskibroj = marker.postanski_broj;
var zupanija = marker.nazivZupanije;
var html = "<b>" + sadrzaj + "</b> <br/>" + adresa +",<br/>"+postanskibroj+" "+grad+",<br/>"+zupanija;
var markerLatlng = new google.maps.LatLng(parseFloat(marker.lat),parseFloat(marker.lng));
var mark = new google.maps.Marker({
map: map,
position: markerLatlng,
icon: marker.slika
});
var infoWindow = new google.maps.InfoWindow;
google.maps.event.addListener(mark, 'click', function(){
infoWindow.setContent(html);
infoWindow.open(map, mark);
});
return mark;
}
function doNothing(){} //very appropriately named function. whats it for?
I also fixed up several small errors in the code, such as
info window was spelt wrong inside your bind function "infowWindow"
your infoWindow listener need to bind to mark not marker
you don't really need to individually extract out each variable from marker
Also, you need to call the load() function from somewhere. Maybe put onLoad="load()" on your body object or top level div. Or use the google DOM listener:
google.maps.event.addDomListener(window, 'load', load);
This will execute your load() function when the window is ready.
You have lo leave
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 45.327168, lng: 14.442902},
zoom: 13
});
out of the commented area, otherwise you're not initializing it.
I am a begginner in javascript, and I know that my code is a little messy. I feel as though I may have stepped on my own foot here but I am really hoping that there is some sort of work around.
What I am wondering is what the best way to add the event listener to the anchors is. Right now, I have a loop that sets all the markers on the map (so I didn't have to write the line of code each time for each marker) but looking back at it I am wondering if there is even a way to add an event listener now.
I have a list of links on the page, and I have an array full of data that i use to tag various things. What I need is to be able to click on the link (where it says "map it!") and for the info window to be prompted, and then I need to toggle that so that it closes if another one is opened
the website can be found here:
http://www.michiganwinetrail.com
And here is the full javascript page
http://www.michiganwinetrail.com/mainmap2.js
the code for the loop that I need to edit (which can be found at the bottom of that javascript link) is as follows:
function loadMap() {
var centerMich = new google.maps.LatLng(44.229457, -85.100098);
var myOptions = {
center: centerMich,
zoom: 7,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("mainMichMap"), myOptions);
var homesouthwestDiv = document.createElement('div');
var homenorthwestDiv = document.createElement('div');
var homesoutheastDiv = document.createElement('div');
homesouthwestDiv.index = 1;
homenorthwestDiv.index = 2;
homesoutheastDiv.index = 3;
var homeControl = {
southwest: swRegions(homesouthwestDiv, map),
northwest: nwRegions(homenorthwestDiv, map),
southeast: seRegions(homesoutheastDiv, map),
};
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(homesouthwestDiv);
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(homenorthwestDiv);
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(homesoutheastDiv);
for (var i=0; i<=locations.length; i++) {
locations[i][0] = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
title: locations[i][3],
map: map,
content: locations[i][4]});
var infowindow = new google.maps.InfoWindow({
});
google.maps.event.addListener(locations[i][0], 'click', function() {
infowindow.setContent(this.content);
infowindow.open(map,this);
});
}
}
On click of the link you need to do something like this:
var myHtml = "<h2 class=\"firstHeading\">" + winery.name + "</h2>";
map.openInfoWindowHtml(new GLatLng(winery.fltLat, winery.fltLng), myHtml);
I had done a similar demo some time ago: http://dipoletech.com/beermenu/
I'm trying to write a function, that gives a lat & long, a name and a picture as formal parameters, so a marker on the map will display when clicked: the name and picture.
It seems to work, though when I add multiple Markers, the actual parameters of the last call are passed to all. And so every Marker I click, will pop up the same name and picture.
I have no clue what I'm doing wrong here, cause I thought that I scoped everything right.
here is some part of my code
in my Initialise() function, I declared the following:
var marker = add_marker(51.21904,4.32659000000001,"Iggy Jensen","bro.jpg");
fluster.addMarker(marker);
var marker = add_marker(51.20367,4.341480000000047,"John Doe","bro.jpg");
fluster.addMarker(marker);
var marker = add_marker(51.2041539954234,4.327017528991746,"Joske Vermeulen","bro.jpg");
fluster.addMarker(marker);
The function add_marker is written by myself addMarker is a part of Fluster2 a cluster management system that I use.
function add_marker(lat,lng,name,pic) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat,lng),
map: map,
icon: 'icon.png',
title: name
});
infoBubble = new InfoBubble({
maxWidth: 300,
backgroundColor: '#dedddd',
borderWidth: 2,
borderColor: 'rgb(68, 68, 68)'
});
var contentString = '<div id="content">'+
'<h2>'+name+'</h2>'+
'<p><span class="myLabel" style="margin-right:10px">Age </span>21</p>'+
'<p><center><img src="'+pic+'" class="bro_image"></center> </p>'+
'</div>';
var div = document.createElement('DIV');
div.innerHTML = 'No pictures uploaded by this user.';
infoBubble.addTab('Personal', contentString);
infoBubble.addTab('Pictures', div);
google.maps.event.addListener(marker, 'click', function() {
if (!infoBubble.isOpen()) {
infoBubble.open(map, marker);
}
});
return marker;
}
function addTab() {
var title = document.getElementById('tab-title').value;
var content = document.getElementById('tab-content').value;
if (title != '' && content != '') {
infoBubble.addTab(title, content);
}
}
Any help is appreciated! Thanks in advance!
Just add 'var' before infoBubble definition, otherwise everytime you are assigning a new InfoBubble object to the same global variable:
var infoBubble = new InfoBubble({
// ^---------here it is
I have a map with streetview panorama, an infowindow and a draggable marker. After the marker is dragged, a function requests the getPanoramaByLocation to see whether the view service is available. If it's not, it closes the infowindow. That is great but when I click again on the marker the infowindow does not open anymore. Do you know what is wrong please?
tx
var sv = new google.maps.StreetViewService();
function initialize() {
var optionMap = {
zoom: 13,
center: new google.maps.LatLng(47.390251,0.68882),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var myMap = new google.maps.Map(document.getElementById("mapDiv"), optionMap);
var optionsMarker = {
position: new google.maps.LatLng(47.390251,0.68882),
map: myMap,
draggable: true,
title: "my marker"
}
var marker = new google.maps.Marker(optionsMarker);
var infowindowDiv = '<div id="streetview" style="width:300px;height:200px;"' +'</div>';
var infoWindow = new google.maps.InfoWindow({
content: infowindowDiv,
position: myMap.getCenter() });
google.maps.event.addListener(marker, 'click', function() {
infoWindow.open(myMap, marker);
});
google.maps.event.addListener(infoWindow, 'domready', function() {
var panorama = new
google.maps.StreetViewPanorama(document.getElementById("streetview"));
panorama.setPosition(infoWindow.getPosition());
google.maps.event.addListener(marker, 'dragend', function(event) {
sv.getPanoramaByLocation(event.latLng, 50, processSVData);});
function processSVData(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
var markerPanoID = data.location.pano;
// Set the Pano to use the passed panoID
panorama.setPano(markerPanoID);
panorama.setPov({
heading: 270,
pitch: 0,
zoom: 1
});
panorama.setVisible(true);
}
else {
infoWindow.close();
infoWindow = null;
};
}
});
}
From the GMaps API docs:
close() None Closes this InfoWindow by removing it from the DOM structure.
https://developers.google.com/maps/documentation/javascript/reference#InfoWindow
So... If you close the infowindow, it's gone. For ever. All the more so if you REALLY make sure it's gone by saying "infoWindow = null;" You have to make a new one. My advice would be to refactor your code to have a separate function that creates the infowindow on demand and returns it. In your click event definition, check whether infowindow is null, and if so, grab a new one.
HTH
As the other answer explain, the infobox html is removed from DOM when the user clicks the close button, but the JS object still there.
When you create an infowindow you must call the open method to see it on the map
myInfoWindow.open(mymap);
So, if you listen to the 'closeclick' event and keep the infowindow state
var infoWindowClosed = false;
google.maps.event.addListener(myInfoBox, "closeclick", function () {
infoWindowClosed = true;
});
you can reopen myInfoWindow on demand
if(infoWindowClosed){
myInfoWindow.open(mymap);
}