Knew this would happen — figure out enough things and people come to expect it. Latest situation: a store locator. Should be easy, right? Google APIs are out there, lots of tutorials available, etc. Here Rhythm, go to it!
It’s all in JavaScript.
I don’t know anything about JavaScript.
So a couple questions:
First, from the teach-me-to-fish side, what are the big JavaScript boards and programming sources out there to turn to with similar questions and learning help? The Learn JavaScript basics in 1,486 easy steps kind of sites.
Second, from the can-I-haz-fish side, can someone point me in the right direction here? I have two scripts that, when combined, will do exactly what I want. The first script get me 99 percent of the way there — draws the initial map, searches, finds locations (they’re in a database), and displays the info I want—except the pop-up balloons on the markers don’t have the directions option; that’s in the second script. I’ve tried randomly cutting and pasting (and not so randomly), but to no avail—while I can change some of the information in the pop-ups, I can’t get the to here/from here links to show up. Any help?
Thanks
Rhythm
Script 1:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps AJAX + MySQL/PHP Example</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAYBmYvZ7KQo9O_4RwOlxdhBS1_wxKxGdp2RzRaADWaiSLCsSD_BS1RmboaMTdnmFHgWVfD_1PYRwqIA"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var map;
var geocoder;
function load() {
if (GBrowserIsCompatible()) {
geocoder = new GClientGeocoder();
map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(41.5961, -74.4152), 2);
map.setZoom (16);
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
}
}
function searchLocations() {
var address = document.getElementById('addressInput').value;
geocoder.getLatLng(address, function(latlng) {
if (!latlng) {
alert(address + ' not found');
} else {
searchLocationsNear(latlng);
}
});
}
function searchLocationsNear(center) {
var radius = document.getElementById('radiusSelect').value;
var searchUrl = 'map3.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius;
GDownloadUrl(searchUrl, function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName('marker');
map.clearOverlays();
var sidebar = document.getElementById('sidebar');
sidebar.innerHTML = '';
if (markers.length == 0) {
sidebar.innerHTML = 'No results found.';
map.setCenter(new GLatLng(40, -100), 4);
return;
}
var bounds = new GLatLngBounds();
for (var i = 0; i < markers.length; i++) {
var name = markers*.getAttribute('name');
var zip = markers*.getAttribute('zip');
var type = markers*.getAttribute('type');
var city = markers*.getAttribute('city');
var address = markers*.getAttribute('address');
var distance = parseFloat(markers*.getAttribute('distance'));
var point = new GLatLng(parseFloat(markers*.getAttribute('lat')),
parseFloat(markers*.getAttribute('lng')));
var marker = createMarker(point, name, zip, city, address);
map.addOverlay(marker);
var sidebarEntry = createSidebarEntry(marker, name, zip, address, type, city, distance);
sidebar.appendChild(sidebarEntry);
bounds.extend(point);
}
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
});
}
function createMarker(point, name, zip, address, city) {
var marker = new GMarker(point);
var html = '<b>' + name + '</b> <br/>' + city + ', ' + address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
function createSidebarEntry(marker, name, zip, address, type, city, distance) {
var div = document.createElement('div');
var html = type + '</b> <br/>' + '<b>' + name + '</b> (' + distance.toFixed(1) + ')<br/>' + address + ', ' + city +'</b> <br/>' + zip;
div.innerHTML = html;
div.style.cursor = 'pointer';
div.style.marginBottom = '5px';
GEvent.addDomListener(div, 'click', function() {
GEvent.trigger(marker, 'click');
});
GEvent.addDomListener(div, 'mouseover', function() {
div.style.backgroundColor = '#eee';
});
GEvent.addDomListener(div, 'mouseout', function() {
div.style.backgroundColor = '#fff';
});
return div;
}
//]]>
</script>
</head>
<body onLoad="load()" onUnload="GUnload()">
Address: <input type="text" id="addressInput"/>
Radius: <select id="radiusSelect">
<option value="25" selected>25</option>
<option value="100">100</option>
<option value="200">200</option>
</select>
<input type="button" onClick="searchLocations()" value="Search Locations"/>
<br/>
<br/>
<div style="width:600px; font-family:Arial,
sans-serif; font-size:11px; border:1px solid black">
<table>
<tbody>
<tr id="cm_mapTR">
<td width="200" valign="top"> <div id="sidebar" style="overflow: auto; height: 400px; font-size: 11px; color: #000"></div>
</td>
<td> <div id="map" style="overflow: hidden; width:400px; height:400px"></div> </td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
This is the second script, the one that has the directions in the marker pop-ups.
<!--the lines below go into a map.xml file in the same directory-->
<markers>
<marker lat="35.827818" lng="-86.072576" html="<b/>First Baptist Church</b/> <br /> 405 West Main Street, <br /> Woodbury, TN 37190" label="FBC"/>
</markers>
<!--the lines above go into a map.xml file in the same directory-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Google Maps</title>
<!--insert your API key after key= -->
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAYBmYvZ7KQo9O_4RwOlxdhBS1_wxKxGdp2RzRaADWaiSLCsSD_BS1RmboaMTdnmFHgWVfD_1PYRwqIA" type="text/javascript"></script>
</head>
<!--note the onunload event attached to the body tag-->
<body onunload="GUnload()">
<!--this Div holds the map-->
<!--change the style to fit your needs-->
<div id="map" style="width: 550px; height: 450px; border: 1px solid #000000;"></div>
<!--What to display if JavaScript is disabled in the user's browser-->
<noscript><strong>JavaScript must be enabled in order for you to use Google Maps.</strong><br />
However, it seems JavaScript is either disabled or not supported by your browser. <br />
To view Google Maps, enable JavaScript by changing your browser options, and then
try again.<br /><br />
</noscript>
<script type="text/javascript">
//<![CDATA[
if (GBrowserIsCompatible()) {
// this variable will collect the html which will eventually be placed in the GMapSidebar
var GMapSidebar_html = "";
// arrays to hold copies of the markers and html used by the GMapSidebar
// because the function closure trick doesnt work there
var gmarkers = [];
var htmls = [];
var i = 0;
// arrays to hold variants of the info window html with get direction forms open
var to_htmls = [];
var from_htmls = [];
// A function to create the marker and set up the event window
function createMarker(point,name,html) {
var marker = new GMarker(point);
// The info window version with the "to here" form open
to_htmls* = html + '<br>Directions: <b>To here</b> - <a href="javascript:fromhere(' + i + ')">From here</a>' +
'<br>Start address:<form action="http://maps.google.com/maps" method="get" target="_blank">' +
'<input type="text" SIZE=40 MAXLENGTH=40 name="saddr" id="saddr" value="" /><br>' +
'<INPUT value="Get Directions" TYPE="SUBMIT">' +
'<input type="hidden" name="daddr" value="' + point.lat() + ',' + point.lng() +
// "(" + name + ")" +
'"/>';
// The info window version with the "to here" form open
from_htmls* = html + '<br>Directions: <a href="javascript:tohere(' + i + ')">To here</a> - <b>From here</b>' +
'<br>End address:<form action="http://maps.google.com/maps" method="get"" target="_blank">' +
'<input type="text" SIZE=40 MAXLENGTH=40 name="daddr" id="daddr" value="" /><br>' +
'<INPUT value="Get Directions" TYPE="SUBMIT">' +
'<input type="hidden" name="saddr" value="' + point.lat() + ',' + point.lng() +
// "(" + name + ")" +
'"/>';
// The inactive version of the direction info
html = html + '<br>Directions: <a href="javascript:tohere('+i+')">To here</a> - <a href="javascript:fromhere('+i+')">From here</a>';
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
// save the info we need to use later for the GMapSidebar
gmarkers* = marker;
htmls* = html;
// add a line to the GMapSidebar html
GMapSidebar_html += '<a href="javascript:myclick(' + i + ')">' + name + '</a><br>';
i++;
return marker;
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
gmarkers*.openInfoWindowHtml(htmls*);
}
// functions that open the directions forms
function tohere(i) {
gmarkers*.openInfoWindowHtml(to_htmls*);
}
function fromhere(i) {
gmarkers*.openInfoWindowHtml(from_htmls*);
}
// create the map
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(35.828186,-86.065161), 14);
// Read the data from map.xml
var request = GXmlHttp.create();
request.open("GET", "map.xml", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var xmlDoc = request.responseXML;
// obtain the array of markers and loop through it
var markers = xmlDoc.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers*.getAttribute("lat"));
var lng = parseFloat(markers*.getAttribute("lng"));
var point = new GLatLng(lat,lng);
var html = markers*.getAttribute("html");
var label = markers*.getAttribute("label");
// create the marker
var marker = createMarker(point,label,html);
map.addOverlay(marker);
}
// put the assembled GMapSidebar_html contents into the GMapSidebar div
document.getElementById("GMapSidebar").innerHTML = GMapSidebar_html;
}
}
request.send(null);
}
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
// This Javascript is based on code provided by the
// Blackpool Community Church Javascript Team
// http://www.commchurch.freeserve.co.uk/
// http://www.econym.demon.co.uk/googlemaps/
//]]>
</script>
Lastly, if it makes a difference, here is the script that the first script is pulling location information from
<?php
require("connect.php");
// Get parameters from URL
$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];
// Start XML file, create parent node
$dom = new DOMDocument("1.0");
$node = $dom->createElement("markers");
$parnode = $dom->appendChild($node);
// Opens a connection to a mySQL server
$connection=mysql_connect (localhost, $username, $password);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active mySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die ("Can\'t use the db : " . mysql_error());
}
// Search the rows in the locations table 41.596100 -74.415199
$query = sprintf("SELECT type, city, zip, address, name, lat, lng, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM locations HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",
mysql_real_escape_string($center_lat),
mysql_real_escape_string($center_lng),
mysql_real_escape_string($center_lat),
mysql_real_escape_string($radius));
$result = mysql_query($query);
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
header("Content-type: text/xml");
// Iterate through the rows, adding XML nodes for each
while ($row = @mysql_fetch_assoc($result)){
$node = $dom->createElement("marker");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("name", $row['name']);
$newnode->setAttribute("type", $row['type']);
$newnode->setAttribute("city", $row['city']);
$newnode->setAttribute("zip", $row['zip']);
$newnode->setAttribute("address", $row['address']);
$newnode->setAttribute("lat", $row['lat']);
$newnode->setAttribute("lng", $row['lng']);
$newnode->setAttribute("distance", $row['distance']);
}
echo $dom->saveXML();
?>
Again, thanks