Simple Custom Infoboxes in Bing Maps V7

Bing Maps has built in infoboxes.. These work great if you have basic information text information that you want to display when a user clicks on a pushpin. Some times you may want to passing custom content such as an image. The built infobox control supports passing in custom HTML content via the htmlContent property but using this removes the infobox frame that a lot of users prefer to have. Many people seem to have been trying to get around this limitation by hacking away at the Bing Maps CSS. This is not recommended as a change in the Bing Maps control will likely break any custom code that might be created. This blog post is going to show a simple way to use this custom htmlContent property in an infobox control and still have the standard infobox frame.

The first thing we need in an image of the pointer which we can find by watching what gets loaded into our page when loading the default infobox. Note that if you are going to use any icons or images from the Bing maps control it is best to save a copy locally than to reference it by URL as these images will likely move or be versioned at some point which would break your UI.

We can then create a simple HTML that has the layout of our Infobox. For example:

<div class="infobox">
    <a class="infobox_close" href="javascript:closeInfobox()"><img src="images/close.png"/></a>
    <div class="infobox_content">{content}</div>
</div>
<div class="infobox_pointer"><img src="images/pointer_shadow.png"></div>

Looking at this HTML block we can see that it’s pretty straight forward. We have two main div’s; one wraps the infobox content and close button, the other wraps the infobox pointer image. We can then use CSS to style the infobox as we see fit. For example:

.infobox{
    position:relative;
    background-color:white;
    border:1px solid rgb(136, 136, 136);
    left:0px;
    top:0px;
    width:256px;
}

.infobox_close{
    cursor:pointer;
    position: absolute;
    right: 5px;
    top: 5px;
    border:none;
}

.infobox_content{
    margin:5px;
    font-family: Arial;
    font-size:11px;
    line-height:22px;
}

.infobox_pointer{
    width:33px;
    height:38px;
    overflow:hidden;
    position:relative;
    z-index:1;
    left:20px;
    top:-1px;
}

We can now take this and tie it into a simple map example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <title>Custom Infobox Example</title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

      <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>

      <link rel="StyleSheet" href="infoboxStyles.css" type="text/css">    

      <script type="text/javascript">
        var map = null;
        var pinLayer, pinInfobox;

        //HTML that generates the frame for the custom infobox
        var pushpinFrameHTML = '<div class="infobox"><a class="infobox_close" href="javascript:closeInfobox()"><img src="images/close.png"/></a><div class="infobox_content">{content}</div></div><div class="infobox_pointer"><img src="images/pointer_shadow.png"></div>';

         function GetMap()
         {
            // Initialize the map
            map = new Microsoft.Maps.Map(document.getElementById("myMap"), {credentials:"Your Bing Maps Key", center : new Microsoft.Maps.Location(51.515, -0.155),zoom : 14}); 

            //Create two layers, one for pushpins, the other for the infobox. This way the infobox will always be above the pushpins.
            pinLayer = new Microsoft.Maps.EntityCollection();
            map.entities.push(pinLayer);

            var infoboxLayer = new Microsoft.Maps.EntityCollection();
            map.entities.push(infoboxLayer);

            // Create the info box for the pushpin
            pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0,0), {visible: false});
            infoboxLayer.push(pinInfobox);

            //Add test data
            var pin = new Microsoft.Maps.Pushpin(map.getCenter()); 

            pin.title = "Pin 1";
            pin.description = "This is pin 1<br/><i>Here is custom HTML</i>";

            // Add a handler for the pushpin click event.
            Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);

            pinLayer.push(pin);
         }

         function displayInfobox(e)
         {
             if (e.targetType == "pushpin") {
                var pin = e.target;

                var html = "<span class='infobox_title'>" + pin.title + "</span><br/>" + pin.description;

                pinInfobox.setOptions({
                    visible:true,
                    offset: new Microsoft.Maps.Point(-33, 20),
                    htmlContent: pushpinFrameHTML.replace('{content}',html)
                });

                //set location of infobox
                pinInfobox.setLocation(pin.getLocation());
            }
         }

        function closeInfobox(){
            pinInfobox.setOptions({visible:false});
        }
      </script>
   </head>
   <body onload="GetMap();">
      <div id='myMap' style="position:relative; width:600px; height:400px;"></div>
</html>

If you run the code as is you will be able to display an infobox when you click on the pushpin. The final result should look something like this:

image

You can download the complete source code and images here.

If you are looking for a more advance infobox that repositions itself as you move the map then check out the Custom Infobox module here.

Advertisements

7 thoughts on “Simple Custom Infoboxes in Bing Maps V7

  1. Thanks so much for this. I’m new to v7 of microsoft maps (all my previous work was in 6.3). I was having a lot of trouble with the info boxes showing custom HTML and this did the trick. Much appreciated.

  2. I now use custom infoboxes on my web app. I found that Chrome often renders the pointer 1px too low, so the box border is not blanked out as it should be. To rectify this I moved the pointer up one pixel and made the top corners transparent leaving the rest of the top row solid.
    Thanks for the article.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s