TabbedMaxContent with Multiple Points

Last time I showed how to use the TabbedMaxContent from Google to display large amounts of possibly dynamic data. The example I used only had one GMarker, though, which isn’t especially useful. Most map users want to have multiple points. So, with that in mind, here are some of the techniques that you need to use to handle multiple markers that use TabbedMaxContent.

First, we need some latitude, longitude, and label triples. Since this example isn’t using AJAX to retrieve the information, we’re going to use some fixed JavaScript assignments:

pointdefs[0] = new Object;
pointdefs[0].latitude  = 35.6058733469;
pointdefs[0].longitude = -77.3629331589;
pointdefs[0].label     = "Austin Building";

pointdefs[1] = new Object;
pointdefs[1].latitude  =  35.606426;
pointdefs[1].longitude = -77.364464;
pointdefs[1].label     = "Rawl Building";

pointdefs[2] = new Object;
pointdefs[2].latitude  =  35.613659;
pointdefs[2].longitude = -77.370827;
pointdefs[2].label     = "Cotanche Building";

There’s nothing special here, we’re just creating an array of objects to make life easier. Each object has three attributes, the previously mentioned latitude, longitude, and label. So, we have objects with the information we need, how do we turn these into useful map objects? We will need to loop over the basic geo data and:

  1. create GPoints (which are Google’s latitude/longitude classes)
  2. create a Gmarker from the previous GPoint
  3. create two MaxContentTabs for the GMarker
  4. assign a click event handler to fire off the MaxContentTab open method

All of this functionality can be encapsulated into a single function that returns the constructed GMarker:

function createMarker(point, index, pointdef) {
	var tab1html;
	var tab2html;
	var tab1;
	var tab2;
	var tabs = [];	
	var marker = new GMarker(point);
	tab1html = '

Point ' + index + ' tab 1

'; tab1 = new MaxContentTab('Tab 1', tab1html); tabs.push(tab1); tab2html = '<p>This is the second tab. Here is a random valued Google Chart to give an example of interesting content</p><p id="tab2image"></p>'; tab2 = new MaxContentTab('Tab 2', tab2html); tabs.push(tab2); // HTML for minimized and maximized state of the TabbedMaxContent window var regularInfo = pointdef.label + '<br/ ><a href="javascript:void(0)" onclick="javascript:map.getInfoWindow().maximize()">more information ... </a>'; var summaryInfo = '<a href="javascript:void(0)" onclick="javascript:map.getInfoWindow().restore()">less information ... </a>'; GEvent.addListener(marker, "click", function() { marker.openMaxContentTabsHtml(map, regularInfo, summaryInfo, tabs, { maxTitle: 'Detailed Information'} ); }); return marker; }

In the code above, we’re passing in a GPoint, an index (for labeling purposes), and a pointdef (one of the objects in our array). Other than handling an object’s attributes for the label, the code is pretty much the same as our previous MaxContentTab example. Using a function gives us the isolation of the constructed GMarker to prevent the JavaScript engine from reusing the string data and giving us the proper results when we click each GMarker.

All that remains is a driving loop that calls the function:

			for (var i = 0; i < pointdefs.length; i++) {
				// Single GLatLng instance
				var point;

				point =  new GLatLng(pointdefs[i].latitude, pointdefs[i].longitude);			
				marker = createMarker(point, i, pointdefs[i]);

				// Add this marker to the map itself

In real production code, you'd want to create a variable to contain the array length, rather than having it evaluated for every element of pointdefs. In addition, you could move the GPoint assignment to the createMarker function, rather than passing it in as I've done here. The point creation in the loop, rather than the function, is a remnant of earlier examples I created for myself.

The final line of code in the loop, markers.push(marker), is not needed for our example in this posting. It's a taste of things to come, an array to allow for a sidebar that gives you alternate means of accessing your map markers.

Update: I almost forgot my link to a live example that puts all the code together.