hackification

Homepage

...rediscover the joy of coding

Developing a jQuery Plug-In: Virtual Earth Maps

One of the really nice features of the jQuery JavaScript library is that it allows you to very easily write plug-in methods for it. Custom jQuery plug-ins are called by the end-user in exactly the same way as the core jQuery methods, and make use of the powerful querying syntax. On top of all that, they're really easy to write! In this article, I'll explain how to write a jQuery plug-in that displays postal addresses as Virtual Earth maps.

Click here for a demo of the code in this example.
Imagine There's No JavaScript

The first thing you need to do before writing a plug-in is to consider what pattern of HTML elements you're trying to re-present to the user. One useful starting point is to imagine how you'd present the information if there was no such thing as JavaScript. Since I want to present an address, my semantic HTML will look something like this:
<div class="address">
  2 Bradford Close, Exmouth, EX8 5PF
</div>
That is, in the absense of JavaScript, my page will still make some sort of sense. Another way of thinking about this is that my page will gracefully degrade if the user doesn't have JavaScript enabled (or, for instance, if Google crawls my site).

jQuery Plug-In Architecture

To create a plug-in method that jQuery can make use of, simply add it to the 'fn' property of jQuery:
jQuery.fn.createInlineVirtualEarthMap = function() { ... }
Remember that jQuery allows us to operate on sets of elements. When developing a plug-in, these elements are available via the 'this' keyword. Since we usually want to operate on all of the elements, a plug-in function usually has the form:
jQuery.fn.createInlineVirtualEarthMap = function() {
  return this.each(function() { ... });
}
(The value of the 'each' function call is returned to permit chaining).

Virtual Earth API

Note: I've used the Virtual Earth API here instead of Google Maps because of ease-of-use issues: although I think Google Maps is the better product (and easier API), Google has unfortuntely decided that to use their API you must either apply for a key (locked to one domain), or include some obfuscated characters (locked to one address). Since this code is based on that of EasyAs123Web.com, which allows users to create their own domains, I've been forced to use Virtual Earth.

Before using the Virtual Earth API, you must obviously include the appropriate script:
<script charset="UTF-8" type="text/javascript"
  src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&mkt=en-gb"></script>
With that in place, you can then create a map in an element using code such as this:
var map = new VEMap('id-of-map-div');
map.LoadMap();
map.HideDashboard();
map.Find(null, 'street address', null, null, 0, 1, true, true, true, true,
  function() { map.SetZoomLevel(16); });
(I've picked a few appropriate values to simply select the first found address. I'm using a callback on the 'Find' method to set the zoom level to a hardcoded value).

Generating IDs

As you can see, the Virtual Earth API expects to be passed the ID of the control to create a map in. But what if the element doesn't have an ID, as in my example?

There's a useful function you can add to jQuery for cases like this:
if (!jQuery.generateId) {
  jQuery.generateId = function() {
    return arguments.callee.prefix + arguments.callee.count++;
  };
  jQuery.generateId.prefix = 'jq$';
  jQuery.generateId.count = 0;

jQuery.fn.generateId = function() { return this.each(function() { this.id = $.generateId(); }); }; }
Note that the function can either be called as a 'static' method:
var id = $.generateId();
Or as a query method:
$('.whatever').generateId();
(And also note that it's added to jQuery as a plug-in method, exactly as described earlier).

The Final Plug-In

So now we have everything necessary to create our plug-in:
jQuery.fn.createInlineVirtualEarthMap = function() {
  return this.each(function() {
    if (!this.id) {
      $(this).generateId();
    }

var address = $(this).text(); var map = new VEMap(this.id);

map.LoadMap(); map.HideDashboard(); map.Find(null, address, null, null, 0, 1, true, true, true, true, function() { map.SetZoomLevel(16); }); });
Of course, if you were creating a plug-in for general use, you'd probably want to allow the user to pass parameters to control the zoom level and other aspects of the map, but since the purpose of this tutorial is only to demonstrate the basics of creating jQuery plug-ins, I haven't bothered.

Client Code

To use this plug-in, it's a simple matter to call it from a jQuery selector:
$('.address').createInlineVirtualEarthMap();
(In the linked example I've applied a style to the class to assign a width and height to the map, and the above call is made in a document.ready block).
Click here for a demo of the code in this example.