I'm trying to get some old code working with the latest Google Maps API. But probably like a majority of the people asking questions, have zero experience with Javascript let alone the API.
If someone could assist, I'd greatly appreciate any help in getting this working properly. Thanks..
The module is the XMod Pro module for DNN. This allows you many options and it's a very powerful module to create items for your webpages, etc. Sometime ago, someone posting information about how to get the Google Maps API working within XMod Pro. The lat and long information about a location is coming from a database where people enter the information about a location. The markers are then put onto the map; which is a standard DIV on the page as well. XMod Pro labels this database information with a double-bracket; e.g. [[Title]] for the title.
When someone clicks on the link for location title, it's to take them to that location on the map and show them information (again from the
database) in the pop-up. This portion isn't working; nor any of the marker information.
I believe the issue is with the JavaScript, but what exactly is causing the issues, I don't know.
Below is the XMod Pro code and most of the pertinent information is stored within the . Thank you again..
<headertemplate>
<a name="HeaderTop"></a>
<div width="150px" height="40px" style="color:black;background-
color:white;padding-bottom:10px;font-family:Georgia;font-size:
14px"><strong>Click an Item</strong></div>
</headertemplate>
<itemtemplate>
<script type="text/javascript">
var i = i + 1;
x[i] = [[Lat]];
y[i] = [[Long]];
d[i] = '<table><tr><td>[[Title]]</td></
tr><tr><td>[[Description]]</td></tr><tr><td>[[Country]]</td></
tr><tr><td>[[Region]]</td></tr><tr><td>[[Email]]</td></tr></table>';
document.write('<div style="padding-bottom:
8px;color:black;background-color:white" width="150px"
onclick="myGclick(' + i + ');">')
</script>
<strong>
<table>
<tr><td colspan="2"><a href="#HeaderTop"><div style="color:
#a41d21;font-size: 13px">[[Title]]</div></a></td></tr>
<tr><td colspan="2">[[Description]]</td></tr>
<tr><td>[[Country]]</td><td>[[Region]]</td></tr>
</table>
</div>
<xmod:scriptblock scriptid="GoogleMapScripts"
registeronce="true" blocktype="ClientScript">
<script src="http://maps.google.com/maps?
file=api&v=2.x&key=ABQIAAAAHrao_r7BKX4cQI0SxCQVHxRXbr2uTTbz5TwhEXAt1Cz65pgUPxQJAHBbHO1MuQeh5aRNkFOL-
Ozptw" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var map = null;
var geocoder = null;
var x=new Array()
var y=new Array()
var d=new Array()
var myGclick = [];
var gmarkers = [];
// This function picks up the click and opens the corresponding info window
myGclick = function myGclick(i) {
GEvent.trigger(gmarkers[i], "click");
}
oldLoad = window.onload;
window.onload = function load(){
if(oldLoad){
oldLoad();
}
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(40, -98), 3);
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.addControl(new GOverviewMapControl());
// Creates a marker at the given point with the given number label
function createMarker(point, d) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(d);
});
// save the info we need to use later for the side_bar
gmarkers[i] = marker;
return marker;
}
for (var i = 0; i < 999; i++) {
var point = new GLatLng(x[i],
y[i]);
if ((x[i] == undefined)){break}
map.addOverlay(createMarker(point, d[i]));
}
}
}
//]]>
</script>
</xmod:scriptblock>
</itemtemplate>
<footertemplate>
</footertemplate>
<noitemstemplate>
<strong>nothing in table</strong>
</noitemstemplate>
<detailtemplate>
</detailtemplate>
</xmod:template>
Does it bring up any errors/messages in Inspector or Firebug?
In Google Maps API V5, my addMarker code was something like the below, where I've placed the infoWindow content straight into the marker.
function addMarker(map, latitude, longitude, heading, title, content){
var latlong = new google.maps.LatLng(latitude, longitude);
var markerOptions = {
position: latlong,
map: map,
title: title,
clickable: true,
icon: 'marker.png',
};
//create marker object
var marker = new google.maps.Marker(markerOptions);
var infoWindowOptions = {
content: content,
position: latlong
};
//info window object
var infoWindow = new google.maps.InfoWindow(infoWindowOptions);
//add click event listener on marker, to bring up infoWindow
google.maps.event.addListener(marker, "click",function(){
infoWindow.open(map);
});
}
When I was working on this, I used alot the documentation here: developers.google.com/maps/documentation/javascript/overlays for Overlays and Markers
I'm sorry I do not know about XMode Pro, but maybe you could note some differences from the old API to the new.
Related
Want to output the latitude and longitude of the marker point in the 2 input boxes below and then also save them but that can happen later. As the user drags around the marker, the latitude and longitude should keep updating. This is the code I have already:
Output
JS
HTML
Please help, I've tried to debug by adding the console.log but it isn't outputting anything which may suggest where the problem is. At least I can't see anything in Chrome dev tools. When I try to debug using Visual Studio breakpoints, none of it loads so I can't do it that way. I've tried a bunch of other stuff as well.
This is the javascript:
var map;
var marker = false;
function initMap() {
var centerOfMap = new google.maps.LatLng(51.487987, -0.237269); // St Paul's School
var options = {
center: centerOfMap,
zoom: 10
};
// extantiate a map object
map = new google.maps.Map(document.getElementById('map'), options);
marker = new google.maps.Marker({
position: centerOfMap,
map: map,
title: 'Drag me around',
draggable: true
});
google.maps.event.addListener(marker, 'dragend', function (event) {
markerLocation();
});
markerLocation();}
function markerLocation() {
// give the information back to the HTML
var currentLocation = marker.getPosition();
console.log(currentLocation.lat());
document.getElementById("lat").value = String.valueOf( currentLocation.lat());
document.getElementById("lng").value = String.valueOf( currentLocation.lng());
}
google.maps.event.addDomListener(window, 'load', initMap);
This is the HTML:
<div class="insert-location">
<p>Select a location where the task will be carried out. Click on a location to select it. Drag the marker to change it.</p>
<div id="map"></div>
<input type="text" id="lat" readonly="readonly"><br>
<input type="text" id="lng" readonly="readonly">
</div>
Ok, here is a working example of how I solved it (add you api key):
http://jsbin.com/rinayek/1/edit?html,css,js,output
1st replace this:
document.getElementById("lat").value = String.valueOf( currentLocation.lat());
document.getElementById("lng").value = String.valueOf( currentLocation.lng());
for this:
document.getElementById("lat").value = currentLocation.lat();
document.getElementById("lng").value = currentLocation.lng();
2nd make your <div id="map"> that is not children of <div class="insert-location">
For the rest you are ok, check the example for more clarity
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 have been trying to convert this code from APIv2 to v3 but I can't get it to work. Would someone help me find the error?
The maps do not start and I don't understand why. I have been using this same code but with the code for v2 API in the past without issues but right now I can´t see were the problem is.
My code is:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?
v=3.exp&sensor=false"></script>
<script type="text/javascript">
var map;
{if $listing.location_is_set}
var zoom = 15;
{else}
var zoom = 7;
{/if}
{literal}
var latitude = {/literal}{$geoData.latitude}{literal};
var longitude = {/literal}{$geoData.longitude}{literal};
$(document).ready(function(){
map = new google.maps.Map(document.getElementById("map-canvas"));
map.setCenter(new google.maps.LatLng(latitude, longitude), zoom);
map.addControl(new google.maps.SmallMapControl());
map.addControl(new google.maps.MapTypeControl());
map.addControl(new google.maps.ScaleControl());
map.addControl(new google.maps.OverviewMapControl());
var point = new google.maps.LatLng(latitude, longitude);
var marker = new google.maps.Marker(point, {draggable: true});
google.maps.event.addListener(marker, "dragstart", function() {
map.closeInfoWindow();
});
google.maps.event.addListener(marker, "dragend", function() {
$("#m_lat").val(marker.getLatLng().lat());
$("#m_lon").val(marker.getLatLng().lng());
});
google.maps.event.addListener(map, 'click', function(overlay,
latlng) {
marker.setLatLng(latlng);
$("#m_lat").val(marker.getLatLng().lat());
$("#m_lon").val(marker.getLatLng().lng());
});
map.addOverlay(marker);
}
);
</script>
{/literal}
This is the code in your template (smarty-powered ?).
As a first step, rather look at the generated javascript (view source from browser)
It will avoid to focus on JS if it's a template-related problem.
Using Google Maps Javascript V3, I have a map set up with some markers. I have a listener on each marker that pops up an InfoWindow on a click event. This works just fine. The problem is when I click on any link on the page and then browse back to the original page, the InfoWindows stop displaying. I have put in alert statements in the listener, so I know the listener is running, but I cannot figure out why the InfoWindows are not showing up.
Here is my code:
<script type="text/javascript">
var map;
var viewable;
var markerArray = new Array();
var infoWindow;
function initialize() {
infoWindow = new google.maps.InfoWindow({ content: "holding..." });
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 15,
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var bounds = new google.maps.LatLngBounds();
var loop_latlng = new google.maps.LatLng( 42.341111, -71.080707 );
marker = addMarker( loop_latlng, "<strong>$1,495.00</strong> <br> Columbus Ave <br> 0 beds / 1 baths <br> <img src='/images/71428455_0.jpg' width=150> <br> <a href='/mls_rn/8305'>get more details</a>" );
bounds.extend(loop_latlng);
var loop_latlng = new google.maps.LatLng( 42.340022, -71.0657278 );
marker = addMarker( loop_latlng, "<strong>$2,000.00</strong> <br> Union Park St <br> 2 beds / 1 baths <br> <img src='/images/71426623_0.jpg' width=150> <br> <a href='/mls_rn/8253'>get more details</a>" );
bounds.extend(loop_latlng);
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
showMarkers();
}
function addMarker(location,contentString) {
var iw = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: location,
animation: google.maps.Animation.DROP,
content: contentString,
map: map
});
google.maps.event.addListener(marker,'click',function(){
infoWindow.setContent(this.content);
infoWindow.open(map,this);
});
markerArray.push(marker);
return marker;
}
// display all the markers on the map
function showMarkers() {
if (markerArray) {
for ( i in markerArray ) {
markerArray[i].setMap(map);
}
}
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyCICKRjJ3Vo_l2hy5uV7GdkYBot6jCtZzI&sensor=true&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
I think this actually may be a Rails issue. If I cut and paste this into an HTML document, it seems to work just fine; however, within my Rails app, I'm seeing the off behaviour. The one thing I notice is that the maps seems to reinitialize in the pure HTML case, but doesn't seem to do so in Rails. I'll look into this more and comment. If anyone has seen this before; however, please chime in!
The behavior you describe doesn't happen for me on the official info windows samples, so i'd expect your code to behave the exact same way.
You would need to manually program for such functionality. On HTML5 compliant browsers, you can use the pageshow event to open the info window manually. However all current (less than 10.0) versions of Internet Explorer don't support the event so you would also have to handle this in the window load event.
I have a Google map that is showing a number of markers. When the user moves the map, the markers are redrawn for the new boundaries, using the code below:
GEvent.addListener(map, "moveend", function() {
var newBounds = map.getBounds();
for(var i = 0; i < places_json.places.length ; i++) {
// if marker is within the new bounds then do...
var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
var html = "blah";
var marker = createMarker(latlng, html);
map.addOverlay(marker);
}
});
My question is simple. If the user has clicked on a marker so that it is showing an open info window, currently when the boundaries are redrawn the info window is closed, because the marker is added again from scratch. How can I prevent this?
It is not ideal, because often the boundaries are redrawn when the user clicks on a marker and the map moves to display the info window - so the info window appears and then disappears again :)
I guess there are a couple of possible ways:
remember which marker has an open info window, and open it again when the markers are redrawn
don't actually re-add the marker with an open info window, just leave it there
However, both require the marker with an open window to have some kind of ID number, and I don't know that this is actually the case in the Google Maps API. Anyone?
----------UPDATE------------------
I've tried doing it by loading the markers into an initial array, as suggested. This loads OK, but the page crashes after the map is dragged.
<script type="text/javascript" src="{{ MEDIA_URL }}js/markerclusterer.js"></script>
<script type='text/javascript'>
function createMarker(point,html, hideMarker) {
//alert('createMarker');
var icon = new GIcon(G_DEFAULT_ICON);
icon.image = "http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png";
var tmpMarker = new GMarker(point, {icon: icon, hide: hideMarker});
GEvent.addListener(tmpMarker, "click", function() {
tmpMarker.openInfoWindowHtml(html);
});
return tmpMarker;
}
var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
var mapLatLng = new GLatLng({{ place.lat }}, {{ place.lon }});
map.setCenter(mapLatLng, 12);
map.addOverlay(new GMarker(mapLatLng));
// load initial markers from json array
var markers = [];
var initialBounds = map.getBounds();
for(var i = 0; i < places_json.places.length ; i++) {
var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
var html = "<strong><a href='/place/" + places_json.places[i].placesidx + "/" + places_json.places[i].area + "'>" + places_json.places[i].area + "</a></strong><br/>" + places_json.places[i].county;
var hideMarker = true;
if((initialBounds.getSouthWest().lat() < places_json.places[i].lat) && (places_json.places[i].lat < initialBounds.getNorthEast().lat()) && (initialBounds.getSouthWest().lng() < places_json.places[i].lon) && (places_json.places[i].lon < initialBounds.getNorthEast().lng()) && (places_json.places[i].placesidx != {{ place.placesidx }})) {
hideMarker = false;
}
var marker = createMarker(latlng, html, hideMarker);
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers, {maxZoom: 11});
</script>
You should probably create all your markers at an initial stage with your createMarker() method, and store the returned GMarker objects inside an array. Make sure to set the hide: true property in GMarkerOptions when you create your markers, so that they would be created as hidden by default.
Then instead of iterating through places_json.places, you could iterate through your new GMarker array. You would be able to get the coordinates of each marker with the GMarker.getLatLng() method, with which to check if each marker lies within the bounds.
Finally simply call GMarker.show() for markers that lie within the bounds, or GMarker.hide() to hide them.
You would eliminate the expensive destruction/creation of markers on each map movement. As a positive-side effect, this will also solve your GInfoWindow problem.
If you're using that many markers, make sure you use GMarkerManager. It's designed for many markers, with only a few visible at once.
http://mapki.com/wiki/Marker_Optimization_Tips