Over the years Iíve taught myself enough HTML, PHP, and MySQL to handle a wide range of Web pages. Iím far from an expert, but Iím now labeled as the person to give technical-seeming projects to.

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 (yet--this is great motivation to pick up the basics and beyond!).

Iíve gotten fairly far ó I found an excellent tutorial that let me build the basic map, connect it to a database of locations, and search within select radii. I can change the distances, some of the descriptors, fields, etc. Great. But I need the pop-up balloons on the map to give the ďto hereĒ and ďfrom hereĒdirections options.

I found a second script that seems to do that cleanly, but unfortunately, I canít seem to figure out how to combine the two ó how to get the pop-up directions option from script 2 merged into the script 1. Iíve tried various copy and pastings, but to no avail.

Can someone please help guide me in the right direction?

Thanks!

Rhythm




Script 1, this one does just about everything I need (sans directions). Itís from http://code.google.com/support/bin/a...34&topic=11364
Code:
 <!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[i].getAttribute('name');
         var zip = markers[i].getAttribute('zip');
		 var type = markers[i].getAttribute('type');
		 var city = markers[i].getAttribute('city');
         var address = markers[i].getAttribute('address');
         var distance = parseFloat(markers[i].getAttribute('distance'));
         var point = new GLatLng(parseFloat(markers[i].getAttribute('lat')),
                                 parseFloat(markers[i].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. Itís from here: http://www.mandladventures.com/2006/...ogle-maps-api/
Code:
 <!--the lines below go into a map.xml file in the same directory-->
<markers>
  <marker lat="35.827818" lng="-86.072576" html="&lt;b/&gt;First Baptist Church&lt;/b/&gt; &lt;br /&gt; 405 West Main Street, &lt;br /&gt; 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&amp;v=2&amp;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[i] = 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[i] = 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[i] = marker;
        htmls[i] = 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[i].openInfoWindowHtml(htmls[i]);
      }

      // functions that open the directions forms
      function tohere(i) {
        gmarkers[i].openInfoWindowHtml(to_htmls[i]);
      }
      function fromhere(i) {
        gmarkers[i].openInfoWindowHtml(from_htmls[i]);
      }


      // 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[i].getAttribute("lat"));
            var lng = parseFloat(markers[i].getAttribute("lng"));
            var point = new GLatLng(lat,lng);
            var html = markers[i].getAttribute("html");
            var label = markers[i].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 page that the first script is pulling location information from
Code:
 <?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 for any help!