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
Related
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.
I've seen other questions related to this and none of the solutions I saw seemed to help. Maybe I'm just overlooking something.
Any help would be appreciated.
I have a map that I'm loading upwards of 1000 markers. When a user performs a mouseover on the marker, I need the infowindow to display for that marker where the marker is.
The issue I'm having is that the same infowindow appears over the same marker no matter which marker I mouseover.
I provided a screenshot below that shows the map with the markers and an infowindow. So, no matter which marker I mouseover, that same infowindow is shown.
This is the code (gm is an instantiated google.maps object):
for (var i = 0; i < opts.LocationsData.length; i ++) {
var datum = opts.LocationsData[i];
var icon = new gm.MarkerImage(datum.map_pin_loc + datum.map_marker + '.svg',null, null, null, new google.maps.Size(31,51));
var loc = new gm.LatLng(datum.latitude, datum.longitude);
var zi = 500;
if(i>9)
{
datum.map_pin_icon = datum.map_pin_loc + 'dot1.svg';
icon = new gm.MarkerImage(datum.map_pin_icon,null, null, null, new google.maps.Size(8,8));
zi=450;
}
var marker = new gm.Marker({
position: loc,
/** title: datum.title != '' ? datum.title : datum.description, **/
icon: icon,
zIndex: zi,
map: map
});
marker.type = 'point';
marker.post_id = datum.pin_id;
marker.scrollAndAnimate = true;
/** (these are used elsewhere in my code for marker management and other purposes) **/
markers.push(marker);
markersLatLngObjs.push(loc);
var infowindow = new gm.InfoWindow({
content: '<strong>' + (datum.title != '' ? datum.title : datum.description) + '</strong>'
});
gm.event.addListener(marker, 'mouseover', function() {
infowindow.open(map,marker);
});
}
The pb is that the mouseover event handler is a closure referencing variables which are unique in the context of the calling function. Better move this part outside the loop to see clearer.
For example you can define a function such as :
function showInfo() {
// called in the context of a marker
var datum = opts.LocationsData[this.placeIndex];
var infowindow = new gm.InfoWindow({
content: '<strong>' + (datum.title != '' ? datum.title : datum.description) + '</strong>'
});
infowindow.open(map, this);
}
just before your loop, then tag the markers with a property placeIndex (for example) in your loop :
marker.placeIndex = i;
and finally bind the handler with :
gm.event.addListener(marker, 'mouseover', showInfo);
Edit: oops, my bad, forgot about the other references, same pb. You can probably replace the marker by 'this' within the handler. I updated the code.
UPDATE
I have added the error up here as its makes it easier to read. Below is the error I now get with that update. P.S it should be InfoBox and not Infobox, I think I made that error somewhere when I typed it up :). So where am I going wrong now? I am not even sure what this error message is saying :
Uncaught TypeError: Cannot read property 'style' of null
InfoBox.setBoxStyle_
InfoBox.setOptions
(anonymous function) PAGE.php:101
N.trigger main.js:23
xK.(anonymous function).e
(anonymous function)
N.trigger main.js:23
F.ie
F.sm
(anonymous function) main.js:11
N.trigger main.js:23
F.Jk
(anonymous function)
OLD POST
I have a custom Google Maps V3 with custom markers being generated with a XML file that is built with a custom DB. I have posted my code below, this all works, only thing is I have now built in the Infobox plugin, which gives me more control over the styling of the marker styles. However they, unlike the Google InfoWindow does not close automatically when another marker is clicked.
This is my load function, which sets the map and build the marker with my XML file,
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(54.500, 355.000),
zoom: 5,
mapTypeId: 'roadmap'
});
downloadUrl("genxml.php?id=<?php echo $VarToUse ?>",function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var number = markers[i].getAttribute("number");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),parseFloat(markers[i].getAttribute("lng")));
var myOptions = {
content: "<b class=\"infoBox_links\">" + name + "</b> <br/>" + address
,disableAutoPan: false
,maxWidth: 0
,pixelOffset: new google.maps.Size(-90, -125)
,zIndex: null
,boxStyle: {
background: "#FFFFFF",
border: "1px solid grey",
width: "170px",
height: "70px",
padding: "8px",
fontSize: "12px",
overflow: "hidden"
}
,closeBoxMargin: "-5px"
,closeBoxURL: "imgs/x_google.png"
,isHidden: false
,pane: "floatPane"
,enableEventPropagation: false
};
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon
});
bindInfoWindow(marker, map, myOptions); //function call to set the markers!
}
});
} //End of function load()
As you can see I have a function that is called within the load, this is my current code, which works fine
function bindInfoWindow(marker, map, myOptions) {
google.maps.event.addListener(marker, 'click', function() {
var ib = new InfoBox(myOptions);
ib.open(map, marker);
});
} //End of bindInfoWindow function!!
This works, custom info boxes with the styles I need are generated, however the current 'open' info box does not close when a new marker is click. And from a number of different attempts and ideas from other people, I am currently working with :
function bindInfoWindow(marker, map, myOptions) {
var ibs = [];
var closeInfoBox = function() {
for (var i in ibs) {
ibs[i].close();
}
}
var ibIndex = ibs.push(new Infobox()) - 1,
ib = ibs[ibIndex];
google.maps.event.addListener(marker, 'click', function() {
closeInfoBox();
ib.setOptions(myOptions);
//var ib = new InfoBox(myOptions);
ib.open(map, marker);
});
}
This code come from Opening only a infobox at a time when multiple markers are displayed on the map
However this only gives me errors, either I have not copied this code right or my set up for the maps different enough for this code not to work (with I don't think is the case). I think it is something I am not doing right. Right now as the code stands, its this line that does not want to work,
var ibIndex = ibs.push(new Infobox()) - 1,
Comes back in the console log with
Uncaught ReferenceError: Infobox is not defined PAGE.php:101
bindInfoWindow PAGE.php:101
(anonymous function) PAGE.php:84
request.onreadystatechange
All ideas most welcome,
Many thanks
Glenn.
Try this. You need the array and closeInfoBox specified outside of the load function, otherwise you just keep resetting the array every time.
var ibs = [];
function closeInfoBox() {
for (var i in ibs) {
ibs[i].close();
}
}
And then you need to push the infobox into the array within the bind function:
function bindInfoWindow(marker, map, myOptions) {
var ib = new Infobox(myOptions);
ibs.push(ib);
google.maps.event.addListener(marker, 'click', function() {
closeInfoBox();
ib.open(map, marker);
});
}
I haven't tested this, but it's similar to what I've done in my code at various points.
However they, unlike the Google InfoWindow does not close automatically when another marker is clicked
This is new to me, a google.maps.InfoWindow will never be closed automatically .
When you only want to have a single InfoBox open use only a single InfoBox-instance for all markers:
function bindInfoWindow(marker, map, myOptions) {
google.maps.event.addListener(marker, 'click', function() {
//create a Infobox that will be used by each marker
if(!this.getMap().get('ib')){this.getMap().set('ib',new InfoBox());}
var ib = this.getMap().get('ib');
ib.setOptions(myOptions);
ib.open(this.getMap(),this);
});
}
OK, I've tried a ton of the examples on here and I just can't seem to get the Info Windows to get the Element Properly Appended. I'm sure this is something with How I've structured this that is simply wrong.
I've made my own Sidebar, and looking at this: http://koti.mbnet.fi/ojalesa/boundsbox/makemarker_sidebar.htm it should be possible. But I can't see what's different than my code.
So here's my AddMarker and Add Sidebar Functions
function addMarker(location, name, content) {
console.log("Adding Marker: "+location)
if (name === "Patient"){
var patient_icon = '<?php echo base_url();?>images/Profile.png';
var marker = new google.maps.Marker({
position: location,
map: map,
title: name,
icon: patient_icon
});
}else{
var marker = new google.maps.Marker({
position: location,
map: map,
title: name
});
}
markersArray.push(marker);
var info = new google.maps.InfoWindow ({content: content})
google.maps.event.addListener(marker, 'click', function(){info.open(map,marker);});
if (name != 'Patient'){
sidebar(name, marker, content)
}
}
function sidebar(name, marker, content){
name = name.replace(/\s+/g, '');
$("<div id='"+name+"'class='even' onclick=' function(){google.maps.event.trigger("+marker+", \"click\")' >"+content+"</div>").appendTo($('#prov_list'));
}
What am I missing that the Onclick Function on the Sidebar elements does Nothing?
Thanks!
You can try something like this, i think the problem was with the string concatenation.
Here's another way to create dom elements:
$("<div/>", {
'id': name,
'class': 'even',
'html': content
}).click(function(){
google.maps.event.trigger(marker, 'click');
}).appendTo($('#prov_list'));
Plain old DHTML:
function sidebar(name, marker, content){
var container = document.getElementById('prov_list');
var myDiv = document.createElement('DIV');
myDiv.onclick = function(){
google.maps.event.trigger(marker, 'click');
}
myDiv.innerHTML = content;
container.appendChild(myDiv);
}
So i have several markers appearing from an array, but i'm having a lot of difficulty setting the content of the InfoWindows that appear
I put the titles in which works great, but when I try to set the content, it doesn't set the content, but still shows the title.
What am I doing wrong?
for (index = 0; index < data.length; ++index) {
locationName = data[index].LocationName;
locationID = data[index].LocationID;
locationX = data[index].XCord;
locationY = data[index].YCord;
var infoContent = '<div><h3>' + data[index].LocationName + '</h3></div><div>' + data[index].LocationID + '</div>';
var mapLocation = new google.maps.LatLng(locationX,locationY);
var marker = new google.maps.Marker({ // Set the marker
position: mapLocation, // Position marker to coordinates
icon: image, //use our image as the marker
map: map, // assign the marker to our map variable
title: data[index].LocationName,
content: infoContent
//draggable:true //Have a guess what this does
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function (marker, index) {
return function () {
infoWindow.setContent(infoContent);
infoWindow.setContent(this.title);
infoWindow.open(map, this);
}
})(marker, index));
var infoWindow = new google.maps.InfoWindow({
content: infoContent
}), marker, index;
}
You are calling setContent twice:
infoWindow.setContent(infoContent);
infoWindow.setContent(this.title);
I guess the last one should be removed.
Edit:
To get the correct infoWindow content, try moving the creation of the eventListener to a function:
// Allow each marker to have an info window
updateInfoWindowOnMarkerClick(marker, infoContent);
//Somewhere after the loop
function updateInfoWindowOnMarkerClick(marker, infoContent){
google.maps.event.addListener(marker, "click", function () {
infoWindow.setContent(infoContent);
infoWindow.open(map, this);
});
}
Have a look at JavaScript closure inside loops – simple practical example for more information about function scope.