Multiple Pushpins and Infoboxes in Bing Maps V7

In Bing Maps an Infobox (or popup) is just another entity that you can treat just like a pushpin. This gives a lot of flexibility in what can be done with the Infobox class. For example, if you want to mark a point on the map you can simply use an infobox instead of a pushpin. This might be ideal for situations where the point you are marking is very small and the pushpin might be too large to mark the point accurately. With this added flexibility we also end up with some added complexity. Because the infobox class is treated as just another entity it is possible for them to be layered behind other entities. This can result in pushpins appearing overtop of the infobox which is usually less than ideal.

In the most situations we want an infobox to appear when a user clicks on a pushpin and we expect this infobox to appear above everything else. We also expect the content of the infobox to be related to the pushpin we clicked.

To accomplish this, a general best practice is to store the metadata for each pushpin as a property of it, that way when an event is fired on the pushpin you have all the metadata associated with it. You can then use one infobox over and over again and just update the position and content when a pushpin is clicked. This will result in a lot less objects in the DOM which will help to ensure good performance. To keep the infobox above your data an easy thing to do is create two EntityCollections, one for data and the other for infoboxes. Add the data EntityCollection to the map first followed by the Infobox EntityCollection. This will ensure that your data (i.e. pushpin) always show up under your infoboxes.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <title></title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
      <script type="text/javascript" src="https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>

      <script type="text/javascript">
          var map = null, infobox, dataLayer;

          function GetMap() {
              // Initialize the map
              map = new Microsoft.Maps.Map(document.getElementById("myMap"),
                         { credentials: "Bing Maps Key" });

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

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

              infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false, offset: new Microsoft.Maps.Point(0, 20) });
              infoboxLayer.push(infobox);

              AddData();
          }

          function AddData() {
              var pin1 = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(0, 30));
              pin1.Title = "This is Pin 1";
              pin1.Description = "Pin 1 description";
              Microsoft.Maps.Events.addHandler(pin1, 'click', displayInfobox);
              dataLayer.push(pin1);

              var pin2 = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(0, -30));
              pin2.Title = "This is Pin 2";
              pin2.Description = "Pin 2 description";
              Microsoft.Maps.Events.addHandler(pin2, 'click', displayInfobox);
              dataLayer.push(pin2);
          }

          function displayInfobox(e) {
              if (e.targetType == 'pushpin') {
                  infobox.setLocation(e.target.getLocation());
                  infobox.setOptions({ visible: true, title: e.target.Title, description: e.target.Description });
              }
          }  
      </script>
   </head>
   <body onload="GetMap();">
      <div id='myMap' style="position:relative;width:600px;height:400px;"></div>
   </body>
</html>

By running this code sample and clicking on a pushpin you will end up with a map similar to this:

clip_image001