Friday, March 13th, 2009
Custom info windows with jQuery and Google Maps
Ben Nolan has a writeup on a new feature in his Weheartplaces application that tweaks the info popup that comes with Google Maps by using a custom overlay. He walks us through an example that ends up with an Infowin class like this:
- // Infowin class for displaying a miniature info window. Does not
- // respond to any events - so you should show and remove the
- // overlay yourself as necessary.
- function Infowin(latlng, html) {
- this.latlng_ = latlng;
- this.html_ = html;
- this.prototype = new GOverlay();
- // Creates the DIV representing the infowindow
- this.initialize = function(map) {
- var div = $('<div />');
- div.css({
- position : 'absolute',
- width : 234
- }).appendTo(map.getPane(G_MAP_FLOAT_PANE))
- this.map_ = map;
- this.div_ = div;
- this.update(html);
- }
- this.update = function(html){
- this.html_ = html;
- this.div_.empty();
- $('<div />').css({
- 'background-image' : 'url(/images/infow-top.png)',
- height : 14,
- padding: '0 0 0 0'
- }).appendTo(this.div_);
- var content = $('<div />').addClass('infowin-content').css({
- 'position' : 'relative',
- 'overflow' : 'hidden',
- 'max-height' : 100,
- 'top' : -5
- }).html(html);
- $('<div />').css({
- 'background-image' : 'url(/images/infow-bottom.png)',
- 'background-position' : 'bottom left',
- 'padding' : '0 10px 30px 10px'
- }).append(content).appendTo(this.div_);
- this.redraw(true);
- }
- // Remove the main DIV from the map pane
- this.remove = function() {
- this.div_.remove();
- }
- // Copy our data to a new instance
- this.copy = function() {
- return new Infowin(this.latlng_, this.html_);
- }
- // Redraw based on the current projection and zoom level
- this.redraw = function(force) {
- if (!force) return;
- var point = this.map_.fromLatLngToDivPixel(this.latlng_);
- // Now position our DIV based on the DIV coordinates of our bounds
- this.div_.css({
- left : point.x - 108,
- top : point.y - this.div_.height() - 22
- });
- }
- }





3.2 rating from 54 votes
Neat feature, but kinda useless. I’m not gonna paste an extra 75 lines of code to waste my bandwith for something I can do with a the normal google maps API. Sure it’s not a nice look, but it’s something.
Also, why is “padding: ‘0 0 0 0′” not turned into “padding: ‘0’”
?
updated with api 3.2
function Infowin_API_3_2(bounds, html) {
this.prototype = new google.maps.OverlayView();
this.prototype.bounds_ = bounds;
this.prototype.html_ = html;
this.prototype.map_ = map;
this.prototype.div_ = null;
this.prototype.setMap(map);
this.prototype.onAdd = function() {
// Note: an overlay’s receipt of onAdd() indicates that
// the map’s panes are now available for attaching
// the overlay to the map via the DOM.
// Create the DIV and set some basic attributes.
var div = document.createElement(‘DIV’);
div.style.borderStyle = “none”;
div.style.borderWidth = “0px”;
div.style.position = “absolute”;
//div.style.width = “150px”;
//div.style.height = “80px”;
div.className=”customInfo”;
div.innerHTML =this.html_;
// Set the overlay’s div_ property to this DIV
this.div_ = div;
// We add an overlay to a map via one of the map’s panes.
// We’ll add this overlay to the overlayImage pane.
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
}
this.prototype.draw = function() {
// Size and position the overlay. We use a southwest and northeast
// position of the overlay to peg it to the correct position and size.
// We need to retrieve the projection from this overlay to do this.
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels coordinates.
// We’ll use these coordinates to resize the DIV.
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image’s DIV to fit the indicated dimensions.
var div = this.div_;
div.style.left = sw.x + ‘px’;
div.style.top = ne.y + ‘px’;
//div.style.width = (ne.x – sw.x) + ‘px’;
//div.style.height = (sw.y – ne.y) + ‘px’;
}
this.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
}