GEOG 863
GIS Mashups for Geospatial Professionals

Adding a Sidebar

PrintPrint

Many of the Google Maps you see embedded on web pages are accompanied by a list of the items that are plotted on the map - sometimes referred to as a sidebar. Often, the items in the sidebar are links that trigger the opening of their associated info windows on the map.

In this section, we're going to add a sidebar to the page we built in the previous section that read and plotted points stored in a shapefile. This sidebar will list the names of the candidate cities as links that open their associated info windows when clicked.

Our approach to this problem will be to add a new sidebar div element to the page. We'll use styles to position the map and sidebar div elements. To construct the HTML that will go in the sidebar div, we'll insert a line into the script's loop that assigns some HTML to a variable. Each time through the loop, the variable will be assigned whatever text it held after the last record was processed, plus the text associated with the current record. In this way, we'll iteratively construct the list of feature info and once the loop is completed assign that list to the innerHTML property of the sidebar div.

With this general strategy in mind, let's go through the steps required to add this functionality one at a time:

  1. First, be sure that you're editing the document from the last page in which you applied the info window fix.

  2. Add a sidebar div element to the <body> section of the page as follows (note that this is HTML and not JavaScript):

    <div id="sidebar"></div>
  3. Next, add the following CSS settings to the style section:

    #map {
       margin: 0;
       padding: 0;
       height: 600px;
       width: 800px;
       float: left;
    }
    
    #sidebar {
      width: 300px;
      height: 600px;
      float: right;
    }
  4. Next, move to the top of the JavaScript section and add the following global variable beneath the global infoWindow variable created in the last section:

    var markers;
  5. Move to the top of initMap() and initialize the markers variable to an empty array:

    markers = [];
    

    The markers variable - as you might have guessed - will be used to store all of the Marker objects as an array.

  6. Next, add a function (perhaps before or after createMarker) that will be used to handle clicks on the links in the sidebar:

    function myclick(num) {
      google.maps.event.trigger(markers[num], "click");
    }

    Note that this function uses the event namespace to open a specific marker's info window by programmatically triggering its click event. The number passed into the function determines which info window gets displayed. For example, if 0 were passed, the info window associated with the first marker in the array would be opened. If 1 were passed, it would open the window associated with the second marker, etc.

  7. Inside the createMarker() function, add the following statement after the var marker statement:

    markers.push(marker);

    This statement uses the push() method of the markers array to add the newly created marker to the end of the array. The last few steps will involve modifications to the render() function.

  8. Just before the loop that processes the shapefile records, declare a new empty string variable to hold the sidebar HTML:

    var side_html = "";
  9. Next, move to the bottom of the loop and add a link to the sidebar HTML that will open the info window for the record being processed:

    side_html += '<a href="javascript:myclick(' + i + ')">' + 
      name + '</a><br />';

    Note how this statement sets the href attribute of the link so that it executes a JavaScript function - namely, the myclick() function we added moments ago. Included in the call to myclick() is the number held in the loop variable i. The link text is pulled from the name variable, which we had already been obtaining in the previous version of the script.

    The side_html variable will be added to incrementally on each pass through the loop. Once the loop is complete, we're ready to use that variable to set the side_bar div's innerHTML property.

  10. Move just beyond the end of the for loop (but still inside the render() function) and set the sidebar HTML as follows:

    document.getElementById("sidebar").innerHTML = side_html;
  11. With that, your page should be ready for testing. If you run into any problems, you can compare your code against mine.

    That was a fairly simple sidebar. Let's say we wanted to provide not just the names of the cities, but also their populations in a tabular format. To do so, we would just need to write some HTML to the side_html variable that's a bit more complex.

  12. Begin by modifying the side_html variable's declaration statement as follows:

    var side_html = '<table style="border-collapse: collapse" border="1" \
      cellpadding="5"> \
        <thead> \
          <tr style="background-color:#e0e0e0"> \
            <th>City</th> \
            <th>Population</th> \
          </tr> \
        </thead> \
        <tbody>';

    This defines a table with a collapsed border (one solid line rather than two detached lines) that is one pixel in width. The cellpadding attribute specifies that the text inside the cells should be five pixels from all edges. A header row is added in a gray background color, followed by a <tbody> start tag, which is used to signal the beginning of the table's body. Note the use of the line continuation character (\) to spread the statement across multiple lines to improve readability.

  13. Inside the loop, the existing side_html statement should be modified like this:

    side_html += 
      '<tr> \
         <td><a href="javascript:myclick(' + i + ')">' + name + '</a></td> \
         <td>' + pop + '</td> \
       </tr>';

    This code adds a new row (<tr>) and two new data cells (<td>) in that row. The first cell contains the link from the original version of this example and the second contains the population value for the current city.

  14. Finally, after the loop we need to close out the <tbody> and <table> tags:

    side_html += 
        '</tbody> \
      </table>';

    Here is my version of this page for your reference.

The last couple of sections have improved on what we had done previously by reading data from a shapefile instead of hard-coding it in the JavaScript and adding a sidebar to make your mashup more informative.  Now, let's have a look at incorporating data in another common format, KML.