Virtual Earth Maps in a template based site site

Introduction

The default mechanism for including Virtual Earth maps, as demonstrated in the Interactive SDK, is to use the onload event on the <body> tag to call the map load function in a script section in the <head> of the page. The script targets a <div> element on the page. e.g.

<!DOCTYPE html
          PUBLIC
          "-//W3C//DTD XHTML 1.0 Strict//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
 <head>
  <title>Live maps demo</title>
  <meta http-equiv="Content-Type" 
        content="text/html; charset=utf-8" />
  <script
    type="text/javascript" 
    src="http://dev.virt  ...  ntrol.ashx?v=6.2"></script>
  <script type="text/javascript">
   var map = null;
        
   function GetMap()
   {
    map = new VEMap('myMap');
    map.LoadMap(new VELatLong(53.1909, -2.8888), 14 ,'a' ,false);
   }   
  </script>
 </head>
 <body onload="GetMap();">
  <h1>Map demo"</h1>
  <div id='myMap' 
       style="position:relative; width:400px; height:400px;">
  </div>
 </body>
</html>   

Test the basic page

The problem

Whether you use a Dynamic Web Template for a static site / PHP site or a MasterPage for an ASP.NET site as your template neither approach allows you to have the onload event in the <body> tag as variable content. This means that you would have to include it in your template and it would be called for every page in your site. Pages with no map content would result in a JavaScript error, unless you provide a dummy function on every page in your site. Neither the JavaScript error, nor the dummy function are completely acceptable solutions.

A sub-problem

The Firefox JavaScript model does not allow direct access to elements within a page using their id. An object must be returned using the document.getElementById function. The Virtual Earth Interactive SDK publishes simple examples which use the shortcut syntax. To work in Firefox the examples need to be changed to use document.getElementById("elementid") instead of using the elementid as a variable directly. We won't deal with this issue in this mini-tutorial.

Solving the main problem

The problem can be solved by moving the call to the map loading function into the body of your page by placing the call in a <script> element. This by itself works across multiple browsers only if the <script> element is place immediately before the </body> tag, i.e. right at the end of the page content. Test the modified page. (Note: view the source to see the code changes.) This approach can be used immediately using a template by adding an editable region at the end of the page, just to hold a <script>element. View an Expression Web Template based version of this modified solution.

However, it is possible to move the <script> element further up the page, into (one of) your existing editable region(s). According to the HTML and XHTML specifications, the position can be made more flexible by including the defer attribute in the <script> tag.

<script type="text/javascript" defer="defer">
  GetMap();
</script>

This should have the effect of deferring execution of the script until after the entire page has loaded. However, the only browser to implement this attribute is Internet Explorer. This may seem like a stumbling block, but the other browsers are capable of executing JavaScript code inside the page, with the proviso that the code does not refer to any page elements which are placed after the JavaScript function call. This means that the map load Javascript function can be placed in a <script> element just under the map container <div>, or beneath any other elements which are used by the function in more complex scenarios. Just make sure the defer attribute is set as this is required by Internet Explorer, as it's Javascript execution model expects elements, such as container <div>s within the page to be fully loaded before script code can access objects within those elements. View an Expression Web Template based version using a single editable area.

MasterPage based templates

An ASP.NET MasterPage simply uses <asp:ContentPlaceHolder> elements instead of the editable region comments in an Expression Web or DreamWeaver template. The concepts map directly across to the ASP.NET development environment. The code for a simple map page built using a default MasterPage structure with one editable region in the <head> of the page and one in the <body> looks like this:

<%@ Page Title="Map demo page" Language="C#" 
         MasterPageFile="~/templatemaps/MasterPage.master"
         AutoEventWireup="true" CodeFile="masterpagemap.aspx.cs"
         Inherits="mpmap" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head"
             Runat="Server">
 <script 
   type="text/javascript"
   src="http://dev.virt  ...  ntrol.ashx?v=6.2"></script>
 <script type="text/javascript">
   var map = null; 
   function GetMap() 
   {
     map = new VEMap('myMap');
     map.LoadMap
             (new VELatLong(53.1909, -2.8888), 14 ,'a' ,false);
   }
 </script>
</asp:Content>
<asp:Content ID="Content2" Runat="Server"
             ContentPlaceHolderID="ContentPlaceHolder1" >
  <div id='myMap' 
       style="position:relative; width:400px; height:400px;">
  </div>
  <script type="text/javascript" defer="defer">
    GetMap();
  </script>
</asp:Content>

Test the MasterPage based version of the simple map page.

How about Google Maps or Yahoo Maps?

This mini-tutorial is really an exposé of JavaScript issues, rather than problems with Virtual Earth, and so the techniques discussed should apply to both Google and Yahoo mapping, though they haven't been tested.

Valid XHTML 1.0! | Valid CSS! | WCAG Approved AA
Page design by: John P Scott - Hosting with: Netcetera