Dev Tip of the Week: Modular plug-in for customizable infobox control

This is a guest blog written by Ricky Brundritt, cofounder and CTO, InKnowledge.

As many of you know, the Bing Maps Locator Wizard is a portal that allows you to generate a Bing Maps Locator in minutes, and then have it hosted in Windows Azure for free. One of the steps in the wizard allows you to customize the style of various elements of the locator.

I was recently working on the wizard and required a highly customizable infobox control that would likely be put in an iframe. This article highlights some of the key features of the modular plug-in we created to allow for this requirement. The result far exceeded our expectations and InKnowledge has since released the code to the Bing Maps community so you can use it in your own applications. Feel free to download the complete source code, with sample implementations and documentation.

Modular Design
The Bing Maps 7.0 Control was released last fall and is a complete rebuild from the ground up when compared to previous versions of Bing Maps. We have seen huge improvements in API performance and the size of the control. One feature of the map control was to use a modular framework; this allows you to register and load modules as they are needed. One result of this is faster loading speeds. Those interested in creating your own reusable modular plug-ins for Bing Maps should have a look at the documentation.

Custom Infoboxes
When the 7.0 Control was originally released there were no infoboxes. The infobox control that Microsoft soon added was a bit different from past versions and was designed to be more flexible. While this is a great improvement, there are a couple of caveats to using this infobox control. The first is that the infobox always points up and to the right and does not reposition itself. This means that infoboxes that are anchored near the top are displayed outside of the map. This can be an issue if the map is being put in an iframe or the map is placed at the end of a webpage. The second caveat is that using custom HTML requires you to also generate the infobox arrow and content area, in addition to the content you want to display. Ideally we would be able to put custom HTML into the frame of the built-in infobox. 

BMLW_Infobox

Positioning
Our goal was to have the content positioned in the center of the map to ensure users can see the infobox. The solution: break the map into quadrants and modify the layout of the infobox such that the content is positioned in the middle of the map. For example, if the anchor point of an infobox is in the lower-left part of the map we want the infobox to be positioned to the right of the anchor point and pushed up. The easiest way to figure out what quadrant the anchor is located in is to convert the anchor coordinate to a pixel coordinate relative to the upper-left corner of the map. To determine if the anchor is to the left or right of the center of the map, simply check to see if the x-pixel coordinate is more or less than half the width of the map. Similar logic can be used to figure out if the anchor is above or below the middle of the map. Once we know if it is left or right of the center and above or below the center, we simply need to place the infobox so that it is in the opposite direction.

The Infobox Arrow
One common issue that developers run into when trying to create customizable infoboxes is with the infobox arrow. In the past, these were almost always images that required edits if you wanted to change something as simple as the color. After a lot of research and experimenting, I found an ingenious solution: CSS borders. Years ago, when the web was young, webpages used to use really big borders to make things look like they were in a frame. As time went on the borders got smaller and smaller to the point where they are either not used or only 1 or 2 pixels wide. So where am I going with this? Well, if you look at a picture frame you might notice that the sides of the frame are connected in the corner at a 45-degree angle. This angle also occurs with CSS borders. If we take this and use a bit of fancy styling, we can modify the color and width of four edges of the border CSS class and generate an arrow. Not only can we generate an arrow, but with a little bit of logic and CSS styling, we can control the width, length. and color of the arrow. Check out this good article on creating angled shapes using the border style.

Additional Features
The API for this custom infobox control is pretty basic. There are only four public methods that are exposed: hide, show, getOptions, and setOptions. The show method is pretty straightforward; it takes in a coordinate and content (either text or HTML). The content will be placed inside the infobox frame, rather than replacing it. By making the input generic we are able to use this infobox with pushpins, polylines, polygons, or on its own. As for options, not only can you set the dimensions and color of the arrow, you can also:
•    Set the background color of the content area of the infobox.
•    Set the color of the border on the infobox.
•    Specify minimum width and height for the content area.
•    Specify an offset distance from the anchor point.
•    Hide the arrow.
•    Hide the default close button.
•    Tether the infobox. The tether option allows one of two user experiences. When enabled the infobox will stay open and reposition itself as you move the map around until you close it. When disabled, the infobox will close when the map moves.

Implementing the Plug-in
Implementing the custom infobox is easy. The first thing you must do is register the plug-in with the map control. You can do this using code similar to the following:

var map, customInfobox;

function GetMap() {
    map = new Microsoft.Maps.Map(document.getElementById(“myMap”), { credentials: “Your_Bing_Maps_Key” });

    //Register and load the Custom Infobox Module
    Microsoft.Maps.registerModule(“CustomInfoboxModule”, “scripts/V7CustomInfobox.min.js”);
    Microsoft.Maps.loadModule(“CustomInfoboxModule”, { callback: function () {
      //Create an instance of the custom infobox control
      customInfobox = new CustomInfobox(map);
    }
    });
}

To display an infobox, specify a coordinate and some content like the following:

customInfobox.show(map.getCenter(), “<b>Hello World</b>”);

We hope you find the plug-in helpful. Be sure to see the complete source code, with sample implementations and documentation. If you have any questions or comments, feel free to send an email to info@inknowledge.co.uk.