This is very much based on the Coda Popup Bubble example for jQuery that’s been going around with a few important differences:
- The information is requested via AJAX, so you don’t have to include all of this extra information in a hidden div. This keeps your markup smaller for grids with tons of names in it.
- When you mouse over another name, the previous one will disappear. If you tried this with the original Coda example, you’d end up with a weird streaking animation since there’s a delay before the div is hidden.
- Works in IE (just turned off the fade animation)
Note that this requires jQuery 1.3.1. I found out that the new .live() functionality is very useful for ajax applications. Previously, if you bind a handler at startup, it will apply to elements that currently exist. The new live() functionality makes it to where you can apply events to elements that are created in the future. This means I can create a new link via ajax and it will still work with the hover tooltip.
Markup
All you need to do is specify a certain css class that jquery expects, and we’re using the “rel” tag to contain data to pass to our ajax helper page.
<a href="<link to person>" rel="4218,a17bee64-8593-436e-a2f8-599a626370df">House, Devon</a> <a href="<link to person>" rel="4218,f6434101-15bf-4c06-bbb2-fbe8c111b948">House, Gregory</a>
JavaScript
Run this on startup, and it will convert all of your links with the “personPopupTrigger” class to have the tooltip.
The container is the global container for the content. It’s repositioned whenever a new link is hovered over.
$(function() { var hideDelay = 500; var currentID; var hideTimer = null; // One instance that's reused to show info for the current person var container = $('<div id="personPopupContainer">' + '<table width="" border="0" cellspacing="0" cellpadding="0" align="center">' + '<tr>' + ' <td></td>' + ' <td></td>' + ' <td></td>' + '</tr>' + '<tr>' + ' <td> </td>' + ' <td><div id="personPopupContent"></div></td>' + ' <td> </td>' + '</tr>' + '<tr>' + ' <td> </td>' + ' <td> </td>' + ' <td></td>' + '</tr>' + '</table>' + '</div>'); $('body').append(container); $('.personPopupTrigger').live('mouseover', function() { // format of 'rel' tag: pageid,personguid var settings = $(this).attr('rel').split(','); var pageID = settings[0]; currentID = settings[1]; // If no guid in url rel tag, don't popup blank if (currentID == '') return; if (hideTimer) clearTimeout(hideTimer); var pos = $(this).offset(); var width = $(this).width(); container.css({ left: (pos.left + width) + 'px', top: pos.top - 5 + 'px' }); $('#personPopupContent').html(' '); $.ajax({ type: 'GET', url: 'personajax.aspx', data: 'page=' + pageID + '&guid=' + currentID, success: function(data) { // Verify that we're pointed to a page that returned the expected results. if (data.indexOf('personPopupResult') < 0) { $('#personPopupContent').html('<span >Page ' + pageID + ' did not return a valid result for person ' + currentID + '.<br />Please have your administrator check the error log.</span>'); } // Verify requested person is this person since we could have multiple ajax // requests out if the server is taking a while. if (data.indexOf(currentID) > 0) { var text = $(data).find('.personPopupResult').html(); $('#personPopupContent').html(text); } } }); container.css('display', 'block'); }); $('.personPopupTrigger').live('mouseout', function() { if (hideTimer) clearTimeout(hideTimer); hideTimer = setTimeout(function() { container.css('display', 'none'); }, hideDelay); }); // Allow mouse over of details without hiding details $('#personPopupContainer').mouseover(function() { if (hideTimer) clearTimeout(hideTimer); }); // Hide after mouseout $('#personPopupContainer').mouseout(function() { if (hideTimer) clearTimeout(hideTimer); hideTimer = setTimeout(function() { container.css('display', 'none'); }, hideDelay); }); });
CSS
#personPopupContainer { position:absolute; left:0; top:0; display:none; z-index: 20000; } .personPopupPopup { } #personPopupContent { background-color: #FFF; min-width: 175px; min-height: 50px; } .personPopupPopup .personPopupImage { margin: 5px; margin-right: 15px; } .personPopupPopup .corner { width: 19px; height: 15px; } .personPopupPopup .topLeft { background: url(../images/personpopup/balloon_topLeft.png) no-repeat; } .personPopupPopup .bottomLeft { background: url(../images/personpopup/balloon_bottomLeft.png) no-repeat; } .personPopupPopup .left { background: url(../images/personpopup/balloon_left.png) repeat-y; } .personPopupPopup .right { background: url(../images/personpopup/balloon_right.png) repeat-y; } .personPopupPopup .topRight { background: url(../images/personpopup/balloon_topRight.png) no-repeat; } .personPopupPopup .bottomRight { background: url(../images/personpopup/balloon_bottomRight.png) no-repeat; } .personPopupPopup .top { background: url(../images/personpopup/balloon_top.png) repeat-x; } .personPopupPopup .bottom { background: url(../images/personpopup/balloon_bottom.png) repeat-x; text-align: center; }
Images:
Downlaod