Google Maps Suggest – Address-Autocompletion with Scriptaculous

Many uses autocompletion on their website. It’s not only an impressiv but also a very user-friendly feature. It can also help to have valid data within a form. But you always have to validate the data on the server before saving them.

Today I want to show you, how easy you can create a autocompletion for Google-Maps-Addresses using Scriptaculous. As you can’t access an external website with an AJAX-Request, we have to use a small Skript as a gateway between Google Maps an your website. So let’s start with this server-side script this time:

$json = json_decode(file_get_contents('http://maps.google.com/maps/geo?output=json&oe=utf8&sensor=false&hl=de&key=YOUR_GOOGLE_MAPS_API_KEY&q='.urlencode($_REQUEST['address'])));

echo '
<ul>';
if(!empty($json->Placemark)){
	foreach($json->Placemark as $value){
		echo '
	<li>'.$value->address.'</li>
';
	}
}
echo '</ul>
';

We send a search query to Google Maps using the “q” parameter for the text we want to search for. The “output” parameter defines the data format we want to receive from Google Maps. In this example I use JSON and convert the data into an object using the json_decode() function. But you can also use XML and the simplexml_load_string() function. But as JSON is a much more compact format, I decided to use it for this example.

Another interresting parameter is “hl” which defines the language of the addresses. You might have recognized this parameter using the Google Search. In this case the addresses are returned in German. With this parameter you can quickly change the language of the function for your site.

To be able to set a request to Google Maps, you’ll need a free Google Maps API Key, which you have to add to the “key” parameter (Thanks to paddy who pointed me about the missing key in my example).

After receiving the data from Google Maps and having them converted to an object, we return it to the JavaScript function. In doing so we create a simple unsorted list with one entry per address.

And now we come to the very extensive client-side script. We have to create a form with a text field. We also need a DIV in which the results are shown. Finally we need a JavaScript function that handles the AJAX-Request and the output of the data. Sounds complicated but infact it’s very easy:

<input type="text" id="address" name="address" />
<div id="adresse_choices" class="autocomplete"></div>
<script type="text/javascript">
	new Ajax.Autocompleter('address', 'adresse_choices', 'get_addresses.php');
</script> 

The hole things can be done with only a single line of JavaScript code. Of course you have to include the “prototype.js” and the “scriptaculous.js” in the head before. The Ajax.Autocompleter() function is part of the Scriptaculous API. The final result looks like this:

Google Maps Suggest

The example address ABC-Straße (ABC-Street) isn’t a joke. It’s the address of Google in Germany. Another nice feature of Google Maps is the spell checking. If you e.g. search for “plazt der luftblöcke”, you will succeed in finding the pace in front of the historic German city airport in Berlin. To test the funcionality you can use the little example page. You can also download the source code. I also added a function to the example that highlights the search string:

Demo Download

As you can see, with the help of the Ajax.Autocomplete() function and a server-side script, it is very easy to use data from another site. The PHP script can easily be customized to the remote datasource and its data format. You can also use a similar function from jQuery or other frameworks. But in this case you might have to change the returned data form the PHP script, too.

I hope this example could show you, how you can use autocompletion in many diffrent cases. Do you already worked with external data. Or do you have an idea, but you couldn’t realize it, yet? I would be happy if you leave a comment.

35 comments » Write a comment

    • Hi Paddy,

      thanks for your comment. I have forgotten to add the Google Maps API Key to the example code. I have now added the key to the post content and to the example and example source code download.

      Bernhard

      • the code works really well :). Can we make this code reverse?? i mean like first the user enters the country then we autocomplete city for him after that we autocomplete a place for him in the city.??

  1. Hi,

    Nice script.

    Is there a possibilty to only show the result of the countries: Netherlands and Belgium?

    Thanks.

    • Hi Steffan,

      that should be no problem. I you just query the data from Google and than filter the results by the “CountryNameCode” or “CountryName” field from the XML or JSON against the two countries. Depending on the language you use (the “hl” parameter) you have to use the correct spelling of the country name.

      I hope that gave you an idea on how to solve the problem. If you still have some question, don’t hestitate to leave another comment.

      • I think I’ll write another post about that topic. But something like this should do the trick (untested):

        echo '&lt;ul&gt;';
        if(!empty($json-&gt;Placemark)){
           foreach($json-&gt;Placemark as $value){
        		if(in_array($value-&gt;AddressDetails-&gt;Country-&gt;CountryName, array('Netherlands', 'Belgium'))){
        			echo '&lt;li&gt;'.$value-&gt;address.'&lt;/li&gt;';
        		}
           }
        }
        echo '&lt;/ul&gt;';
        
        • Thank you very much! It works well.
          I wanna quote your first comment.
          “Depending on the language you use (the “hl” parameter) you have to use the correct spelling of the country name.”
          For example ‘array(‘Deutschland’)’

          Greetings

  2. hey
    ich komm mit den vielen skript nicht klar.
    ist es möglich nur ergebnis von deutschland auszugeben und 3 felder inputs dafür: Stadt, Strasse , plz . strasse sollte plz automatisch vervollständigen..hilfe

    • Soweit ich das richtig verstehe möchtest du drei Eingabefelder anbeiten. Zuerst eines für die Stadt und anschließend eines für die Straße sowie für die PLZ. Der Benutzer füllt also zuerst das Feld Stadt aus und dann das Feld Straße. Wenn er dann auf Straße klickt soll das Feld PLZ automatisch gefüllt werden. Ist das soweit korrekt?

      Falls ja hier der Lösungsansatz. Für das Feld Straße nimmst du den Inhalt des Feldes und hängst den Text “, Deutschland” an. Das schickst du dann über die API an Google Maps. Wenn der Benutzer also z.B: “München” eingetippt hat, dann ergänzt du es zu “München, Deutschland”.

      Für die Straße sieht es dann ähnlich aus, wobei du hier die Werte für “Stadt” und “Straße” per AJAX an dein PHP-Skript übermittelst und diese Anschließend mit “Deutschland” zu einem Text verbindest. Wenn der Benutzer also z.B: “Maximilianstraße” angibt, verbindest du alle Parameter zu dem Text “Maximilianstraße, München, Deutschland”. Von der Google Maps API solltest du dann eine komplette Adresse inkl. PLZ bekommen, aus der du dann die PLZ auslesen und in das Feld PLZ per JavaScript einfügen kannst.

      Ich hoffe du hast ungefähr eine Ahnung, was ich meine und wie das Ganze gemacht werden kann. Vielleicht erstelle ich mal einen neuen Artikel zu dem Thema.

  3. Thanks.
    This is just the script i was looking for.

    One question though: isn’t there a limit on the number of request per day? 2500 per 24hours per IPaddres, I think.
    This starts to count when request are made trought this ‘proxy’ script (get_addresses.php).
    Or isn’t that for these type of requests?

    • There is nedeed a limit of 2,500 request pre day and IP as described here: http://code.google.com/apis/maps/faq.html#geocoder_limit. But as you cannot use the clients IP because of the same origin policy, you can’t avoid that. However, there are ways to do more request. You may buy a Google Maps API Premier account or you use different API that might offer more requests.

      Another way to cope with the limit is to cache request on your server in a database. Just use the form input string a the primary key and store the recieved XML string (or the serialized SimpleXML/JSON object) in the database. You can than query your DB first and afterwards the Google Maps API. That might also result in quicker responses as a query to your DB might be faster than a file_get_contents() to the Google Maps API.

  4. Thanks for the tutorial, which is exactly what i am looking for. I have learned a few important lessons. THANKS!

  5. Hallo,
    super Code danke!
    Eine Frage, wie kann ich idealer Weise im HTML-Bereich z.B. als Input-Feld jeweils Strasse, PLZ, Ort der “Ergebnis-XML” ausgeben?
    Möchte gerne dass der User nur in einem Suchfeld sucht und die gewählten Daten dann auf die Inputfelder verteilt werden. DANKE !!!!

    • Wenn ich dich richtig verstanden habe, möchtest du die zurückgegebene Datei aufdröseln und auf Input-Felder verteilen. Du kannst innerhalb json wie folgt navigieren $json->Placemark->AddressDetails->Country->CountryName->address ?! Ist es das was du meinst? Wie die Struktur genau aussieht kannst du z.B: hier nachlesen.
      http://code.google.com/intl/de-DE/apis/maps/documentation/geocoding/v2/
      Ich hoffe das hilft dir weiter!

      Und danke noch mal an dieser Stelle, funktioniert immer noch gut auf meiner Seite 😉

      • @Parcello
        Suuuuuper vielen Dank
        Irgendwie bin ich zu blöd eine Variable zu setzen.
        Wie würde der Teil in der PHP aussehen? Danke 🙂

    • Im Grunde ja. Aber das Problem ist etwas komplexer. Er muss ja auch die einzelnen Teile der Adresse an den Browser übermitteln, um sie dann dort in die Felder einzufügen. Ich habe das ganze eben mal schnell gecodet. Wenn ich es schaffe, dann gibt es noch heute Abend einen Artikel dazu. Die fertige Lösung kann hier angesehen werden:

      Beispiel Download

  6. Eine Frage noch, gibt es von google eine Api, welche auch noch zulässt, nach Unternehmen zu suchen?
    Bsp. Gebe ich ein Unternehmen und Ort in google maps bekomme ich den kompletten Adressdatensatz des Unternehmens 🙂 danke

    • Die Unternehmenssuche nennt sich Google Places. Dazu gibt es auch eine API: http://code.google.com/intl/de-DE/apis/maps/documentation/places/

      Ich habe sie aber selbst noch nie genutzt, kann dir also nicht genau sagen, wie man sie für eine solche Suche ansprechen muss. Sie liefert aber auch XML mit den Treffern zurück, allerdings in einem ganz anderen Format. Ich denke aber, wenn du meine Beispiele vestanden hast, dann sollte eine Anpassung auf das XML Format kein Problem darstellen.

      Wenn du dazu eine fertige Lösung programmiert hast würden wir uns natürlich auch freuen, wenn du sie mit uns teilst. Du darfst sie auch gerne als Gastautor hier vorstellen 😉

        • Habe es heute erfolglos versucht 🙁
          Wie ich das sehe, kann man mit Längen- und Breitengeraden und einer Kategorie z.B Restaurant Ergebnisse erzielen.
          Mein Ansat analog google maps im Original: schreinerei mustermann hamburg und die Rückgabe der Daten inkl. Telefon bekomme ich nicht him.
          Gruss

        • Hast du es schonmal geschafft zumindest eine Rückgabe zu erreichen? Ich bekomme mit den Beispielen immer ein REQUEST_DENIED zurück, obwohl ich einen gültigen API Kex verwende.

  7. Hallo,
    klasse Sache!
    Ich habe zwei Fragen.
    Darf man auch von einer komerziellen Webseite aus oder wenn ich eine komerzielle Softwareauf diese Googlefunktion zugreifen?

    Viele Grüße
    Horst

    • Soweit ich das aus den AGB rauslese ja. Man darf aber nur eine bestimmte Anzahl Requests pro Tag machen (glaube es sind zur Zeit 25.000 pro Tag). Sollte die eigene Website zu groß sein, kann man eine Lizenz für Google Maps API Premier erwerben.

  8. Super Skript!
    Ich habe nur ein kleines Problem, und zwar will ich Flughäfen suchen lassen. Bei “Flughafen Düsseldorf” funktioniert es einwandfrei, aber z.B. den Flughafen Münster/Osnabrück findet er nicht. Bei Eingabe von “FMO” bekomme ich das Ergebnis davon, aber wenn ich dann wieder genau dieses Ergebnis (Flughafen Münster/Osnabrück (FMO), 48268 Greven, Deutschland) eingebe, wird nichts gefunden. Das hat bestimmt nichts mit deinem Skript zu tun, aber hast du vielleicht eine Idee, wie man das lösen könnte?
    Viele Grüße von Steffi

    • Hallo Steffi,
      das hat tatsächlich nichts mit meinem Skript zu tun. Mein Skript ist ja nur eine Schnittstelle zu den Ergebnissen von Google Maps und ich habe leider keinen Einfluss darauf, was Google liefert. Im Allgemeinen kann man aber sagen, dass es nur Straßennamen kennt, aber keine Gebäude, Einrichtungen, Institutionen oder Firmen an diesen Adressen. Eine Suche nach einem Flughafennamen wird also nicht immer funktionieren.

      • Ich habe noch mal ein bisschen rumprobiert, und es scheint ein Problem zu geben, wenn im Suchstring ein “/” vorkommt. Ich kriegs nur irgendwie nicht hin, den Character richtig zu escapen. Weißt du, wie das geht?

        Außerdem hab ich die zweite Version deines Skriptes laufen, und dort zeigt er nur das erste Suchergebnis. Ich habe dort noch ein

        foreach ($markers_dom->getElementsByTagName(‘Placemark’) as $oneplacemark) {

        eingefügt und schaue dann auf die jeweilige Nummer der items.

  9. Echt tolle Arbeit hier! Vielen Dank!

    Ich frage mich gerade, ob es möglich ist, die auto-fulfill Funktion und die Aufteilung in die Adressbestandteile (zip, etc.) mit dem Google Routenplaner zu kombinieren. Das heißt das ich eine Start- und Zielpunkteingabe mit auto-fulfill (wie bei Google Maps Original)auf meiner Website habe und die eingegebenen Start- und Zielpunkte intern (z.B. für eine Datenbankabfrage) weiterverwenden kann.

    Über eine kurze Einschätzung würde ich mich sehr freuen und mich anschließen sofort an die arbeit begeben. 🙂

    VG Champs

    • Hallo Champs,

      so ganz weiß ich nicht wie genau deine Lösung aussehen soll. Aber folgendes wäre sehr einfach möglich:

      – Du hast zwei Eingabefelder, die jeweils eine Auto-Fill-Funktion haben, eines für die Start- und eines für die Zieladresse
      – Der Benutzer gibt beide Adressen ein und bekommt dann z.B. über die Google Maps API eine Routenplanung präsentiert (oder wird alternativ auf die Google Maps Seite mit einer entsprechenden Routenplanung weitergeleitet)

      Die Routenplanung kann sehr einfach mir der JavaScript API von Google Maps umgesetzt werden. Ein einfaches Beispiel findest du hier: https://google-developers.appspot.com/maps/documentation/javascript/v2/examples/directions-simple

      Das Beispiel der API V3 ist nicht so toll. Aber es funktioniert im Grunde ähnlich. Hier ist eben ein Drop-Down anstelle der beiden Input Felder: https://google-developers.appspot.com/maps/documentation/javascript/examples/directions-simple

      Die Ausgabe der Route als Anweisungen sollte hier auch möglich sein.

      Ich hoffe, dass hilft dir weiter. Wenn nicht, kannst du mir gerne noch einmal eine konkretere Frage stellen.

      Bernhard

Leave a Reply

Your email address will not be published. Required fields are marked *