designing4u.de Yet Another Coding Blog

5May/0810

Google maps and jQuery – drop down and clickable maps

I had to manage google Maps for one of the sites I was working on. Basically there were two possibilities to get the user input. Either a user was forced to use one of the drop down options to define an area of the city he or she is living in, or a user could just click on the exact spot on the map where the marker was placed.

To accomplish this task I wanted to use jQuery framework, from two simple reasons. First of all I wanted to create unobtrusive and cross browser compatible code using JavaScript and second of all I wanted to use simplicity, which jQuery gives us to save my time. Thinking about the claim of jQuery "do more, write less" I started to develop my code. Let's first break it into pieces and you can download all the files at the end of this post.

You can also see working demo here

Let's start with including some necessary libraries. I know this might be obvious for almost all of you, but I want to make it as clear as possible for each one of you reading this post. Please add this two lines in the head section of your document. Please don't forget that we will use v2 of GMap in this example. You can download the jQuery library from their official site www.jquery.com. To get the google Maps API key for you your site, you should go to this address and you can sign up for a key for free.

1
2
<script src="jquery.js" type="text/javascript"></script>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>

You can also include the latest jQuery library directly from their site adding this code in the header of your document.

1
<script src="http://code.jquery.com/jquery-latest.js"></script>

I don't wont to discuss the advantages or disadvantages of both methods but if you want to know more about it you should check the cache possibilities of your browser. In our example I will use the latest code available from jQuery site.

Let's start to break my code into pieces and explain what it does. First we will define a ready event to our page and declare some global variables which we will use later in our function, so the code defined in the ready event will be executed after the DOM will be loaded. You need to place this code in the head section of your document.

1
2
3
4
5
$(document).ready(function() {
    var mark;
    var pointA;
    var pointB;
});

The first thing we need to do is to check if the client's browser is compatible with google maps at all. If this check returns true, we use jQuery to define a place holder for our map. In our case it will be a div tag with an id map. We also assume in this example that it will be the first element in our DOM. We will use Berlin as our example city. If jQuery finds our place holder it initializes the GMap and displays it in our div tag. We set the longitude and latitude in the center of Berlin and we are defining a default zoom level. We add some controls to allow our user to manipulate the map and we we are done with the first step of just displaying the map without including the onload even in the body tag of our document.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(document).ready(function() {
    var mark;
    var pointA;
    var pointB;
    if (GBrowserIsCompatible()) {
        var m = $("#map")[0];
        if(m) {		
            var map = new GMap2(m);
            var start = new GLatLng(52.519563,13.414306);
            var zoomLevel = 10;
            map.setCenter(start, zoomLevel);
            map.addControl(new GSmallMapControl());
        }
	}
});

In the next step we want to give our user a possibility to choose the location by simply reading his' or hers' input. To accomplish this task we add an event listener, which will be triggered when a user clicks on our map. First we perform a check if a marker doesn't exist on our map and if it does we remove. After that we check if a point is defined and if it is we add an overlay, which displays the marker and save the latitude an longitude in our hidden input fields (the HTML code for this example will be shown at the end). We will need this information later to save it in the database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$(document).ready(function() {
    var mark;
    var pointA;
    var pointB;
    if (GBrowserIsCompatible()) {
        var m = $("#map")[0];
        if(m) {		
            var map = new GMap2(m);
            var start = new GLatLng(52.519563,13.414306);
            var zoomLevel = 10;
            map.setCenter(start, zoomLevel);
            map.addControl(new GSmallMapControl());
            GEvent.addListener(map, 'click', function(overlay, point){
                if(mark) {
                    map.removeOverlay(mark);
                }
                if(point) {
                    pointA = new GPoint(point.x, point.y);
                    mark = new GMarker(pointA);
                    map.addOverlay(mark);
                    map.getCenter(point);
                    $('#lng').attr('value',point.x);
                    $('#lat').attr('value',point.y);
                }
            });
        }
    }
});

In the last step we add an event listener, which will be triggered when a user use our drop down menu to choose a district. As I stated before, a user has a form to fill out where he is forced to choose the district of a city. We will use AJAX to retrieve this information from an external php file (map_district.php) to get the geographical location of the districts. It splits the string, which it gets and performs a check, if a marker exists already or not. After that it adds a marker to the map, increases the zoom level and overwrites the location in hidden input tags.

(How to determine the longitude and latitude of a certain place for free, you can read another example of mine here .)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
$(document).ready(function() {
    var mark;
    var pointA;
    var pointB;
    if (GBrowserIsCompatible()) {
        var m = $("#map")[0];
        if(m) {		
            var map = new GMap2(m);
            var start = new GLatLng(52.519563,13.414306);
            var zoomLevel = 10;
            map.setCenter(start, zoomLevel);
            map.addControl(new GSmallMapControl());
 
            GEvent.addListener(map, 'click', function(overlay, point){
                if(mark) {
                    map.removeOverlay(mark);
                }
                if(point) {
                    pointA = new GPoint(point.x, point.y);
                    mark = new GMarker(pointA);
                    map.addOverlay(mark);
                    map.getCenter(point);
                    $('#lng').attr('value',point.x);
                    $('#lat').attr('value',point.y);
                }
            });
            $('#city').change(function(){
                var district = 'district='+$(this).val();
                $.ajax({
                    type: 'POST',
                    data: district,
                    url: 'map_district.php',
                    success: function(r) {
                        var cord = r.split("|");
                        if(mark) {
                            map.removeOverlay(mark);
                        }
                        pointB = new GLatLng(cord[0],cord[1]);
                        mark = new GMarker(pointB);
                        map.addOverlay(mark);
                        map.setCenter(pointB, 14);
                        $('#lat').attr('value',cord[0]);
                        $('#lng').attr('value',cord[1]);
                    }
                });
            });
        }
    }
});

This way even if a user will try to erase a marker, we will still have an information about the last placed marker, which we can save in our database. Last thing I need to mention is the content of php and html files.

I will just reduce this example to two districts, but you can add as many as you want. Basically we call this php file in our AJAX request and use POST method to retrieve the location, which we later use to place a marker.

if($_POST['district']=="Charlottenburg") {
    $lat = "52.51120638909939";
    $lng = "13.299808502197266";
} elseif($_POST['district']=="Friedrichshain") {
    $lat = "52.51360922969275";
    $lng = "13.442888259887695";
}
echo $lat."|".$lng;

In the body section of your document you need to place simple drop down list, a div tag with id map and two hidden input fields.

1
2
3
4
5
6
7
<select name="city" id="city">
    <option value="Charlottenburg">Charlottenburg</option>
    <option value="Friedrichshain">Friedrichshain</option>
</select>
<div id="map" style="width:400px;height:400px;"></div>
<input type="hidden" id="lng" name="lng" value="" />
<input type="hidden" id="lat" name="lat" value="" />

That's all. If you want to download the files you can do it here. I'm waiting for your feedback.

Comments (10) Trackbacks (1)
  1. Nice demo…!!
    Unfortunately, doesnt seem to work on opera 9, but works on other browsers. Any ideas ?

  2. Hi Chris.

    I just checked this demo on Opera 9.27 Build 8841 and it works fine for me. I changed the demo site a little bit, so you can see the geographical lengths in the text now. Can you see them? If you could describe your problem a little bit more precisely, maybe I could help you better.

  3. Hey, can you give a demo for how to create the drop down menu to search through a line kml file? Still using
    #
    # Charlottenburg
    # Friedrichshain
    #

  4. Sorry I meant to quote the “select name=”city” id=”city” Like if you had a line kml file and wanted a drop down menu for the beginning and a drop down menu for the ending location?

  5. Thanks for this.
    I’m new to JQuery and was looking for a solution to a Gmap problem, and this was it.

  6. @Allison

    sorry for a late response, but I was really busy with work. I have more time now and can help you.

    I need some clarification before I write a new example. Do you want to measure the distance between this two points? Or should it just display two markers and according to the drop down you are using remove the respective marker?

  7. Well, I’m not exactly clear if you can use this way for line data instead of point data. Like say I have a kml file with tags referring to the starting building and ending building. Is is possible to create two drop down menus one for the starting building and one for the ending building and then click the sumbit button to search through one kml file of many paths and get the specifications that I want? I was thinking AJAX might be the only way to do this or possibly JQuery with AJAX.

  8. Thanks for taking the time to look into this. I’m not sure if I explained it clearly enough the 2nd time around so I’ll try to paint a better picture of what I’m trying to do. Ok, so I have a line kml file filled with differents routes to take. Within that line kml file I have tags refering to the starting building where the line starts and then another set of tags that include the ending building where the line ends. I’m wanting to use this one file and create a dropdown menu like option value=”Kerr Hall”>Kerr HallLibrary</option ect… Then a second drop down list. Listing the same buildings and then the submit button could search through that one Line kml file so the user would be able to go from Kerr Hall to the Library and find that specific route from the line data.

  9. Hi Allison,

    Yes, this is possible and it should not be that difficult. I’ll try to write an example how to accomplish this and post the link to it here.

  10. Hi again,

    I just wrote an example how you can accomplish that. You can find it here. I hope it will help you :)


Leave a comment


Pages

Categories

Blogroll

Archive

Meta