A jQuery based tooltip solution for a large web application

by Oliver Tue, March 13 2012 01:37

Finally, with an update we rolled out last week, (almost) all tooltips on Camping.Info look and behave similar, differing mostly in positioning and size, but not in the general look and feel. We chose the jQuery Tools Tooltip as the base for our own solution and it got us pretty far, but there were some pitfalls and scenarios that we needed to handle ourselves. This post is about what limitations we experienced and how we dealt with them.

The original

As you can read in the jQuery Tools Tooltip documentation, the tooltip plugin is highly configurable. It can take different elements as the tooltip for any given trigger:

  • the value of title attribute of the trigger element
  • the html element immediately following the trigger
  • the html element immediately following the first parent of the trigger
  • an arbitrary html element on the page.

You can also position the tooltip pretty much wherever you want relatively to the trigger:

jQuery Tools Tooltip Positioning

Our adaptations

Another way to chose the tooltip

We found one more useful way to define the tooltip for a trigger element: if the trigger is e.g. a table cell in an html table and you don’t want to specify a static tooltip for some or all table cells but a different one for each cell or at least a number of cells, it makes sense to define the tooltip element inside the trigger (the table cell). Since this effect was not achievable extending the jQuery Tools Tooltip plugin we started changing their source:

image

Breaking the tooltip out of some parent container

We also faced some problem properly showing tooltips that needed to “break out” of some bounding box, inside which they were defined (i.e. their html markup). This problem e.g. occurred inside elements with style position: relative, which we have a few of on Camping.Info. Our first attempt was to clone the tooltip element and show the clone instead of the original. This worked in almost all cases – until we tried to attach some more behavior to elements inside the tooltip. The behavior, e.g. some click event handler that we expected to fire when clicking on some element inside the tooltip, wouldn’t execute, since we were working with the clone! So we decided to simply move the tooltip up in the DOM tree for the time it is being shown, more precisely just beneath the form tag that we have on all our pages. We create a placeholder at the place where we removed the tooltip to reinsert it again once it’s being hidden. The code we added to the show() method looks like this:

image

… and here’s the counterpart in hide():

image

Now, this works quite well everywhere, independent of the position of the tooltip in the DOM tree.

Global tooltip configuration

Using inline static configuration

One feature we quickly missed was some kind of static tooltip configuration without calling  $(...).tooltip({ settings: ... }) for every single tooltip we wanted to create or hook up, respectively. What we came up with is to use the HTML5 data attributes to define any specific configuration statically inside the trigger element’s html markup. Thus, we need to call the tooltip initialization code only once for the whole page. The configuration now looks like this:

image

We use specific prefixes with the data attributes to make them easier to understand, e.g. data-tt-position for an attribute that is used for tooltips and jq-tt-trigger for a class that is used by some jQuery code for tooltips.

To process this kind of static configuration we need some custom code that will, at some point, call the original (well, modified by now) plugin code. Unfortunately, the jQuery Tools Tooltip plugin was not designed to allow runtime configuration of the tooltip to show, but we found a way using the onBeforeShow and onHide event handlers. The basic idea is to change the global Tooltip configuration during the first method so that the tooltip we will be showing will be configured correctly, and to reset the global configuration once the tooltip has been hidden again. To achieve this, we iterate over all configuration properties that the jQuery Tools Tooltip plugin supports and search for the respective data attributes on the currently processes trigger element. One example would be the position property: to replace the default value provided by the plugin we look for an attribute that’s called data-tt-position and use its value to temporarily overwrite the default value during the onBeforeShow event handler.

Using global profiles

Once we had the static configuration working and started to replace all of those clumsy and overly complicated AjaxControlToolkit HoverMenuExtenders, it quickly turned out that we were copy’n’pasting the same configuration in a thousand places. This was not only ugly and violated the DRY principle, it also lead to some unnecessarily bloated html. As a solution to this maintenance nightmare we came up with profiles that comprise a set of configuration options that would else be repeated over and over again:

image

Now, they lead to some really clean html markup:

image

The only change from using the inline static configuration is to use the profile’s properties – everything else stays the same!

Conclusion

The jQuery Tools Tooltip plugin is a nice, small and highly configurable tool for easy tooltip creation and usage. In a larger web application there a few shortcomings that we’ve addressed here and which we’ve provided working solutions for. We hope to release those changes soon in its own project on our GitHub account.

Happy coding!

Tags:

jQuery | Web Applikationen | Software development | WEB 2.0 | Usability | Design

Rendering problem with flot 0.7 and excanvas in IE8

by Oliver Thu, September 08 2011 02:41

On Camping.info, we use flot 0.7 with jQuery and asynchronous updates for internal click statistics visualization. Unfortunately, we’ve been having some trouble with our flot graph – but only in IE8 and only sometimes! This has been really annoying, especially since we’re expecting a usage growth of this graph and IE8 has a user share of 25%. The problem is that after fetching the graph data from the server the graph sometime won’t appear on the canvas, although it seems to be there as the yellow tooltip suggests when hovering over the graph line. The graph looks like this (broken vs. intact):

image                     image

We were (are?) having a hard time reproducing this bug on our staging system but it would appear from time to time. On our live system we would get it quite often, although a page refresh often helped.

Searching the web for flot+IE8 you’ll get a few results most of which point to the “flot-graphs” Google Group. A search on stackoverflow.com led me to an interesting post called IE8 is sometimes displaying my page correctly, sometimes not, which seemed interesting enough to check out. There, they talk about a problem with the  display:inline-block  CSS rule and that it is error-prone in IE<=8. So I checked the source of excanvas.min.js which is responsible for providing a canvas element to flot in IE browsers below version 9, and sure enough I found this:

   1: a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}

The fix proposed in this answer was to use zoom:1 to force elements with display:inline-block  to have a layout in IE (if you really want to know what that means, here’s more background info). Well, I tried that – to no avail.

The next hint came from a post in the flot-graphs Google Group and proposed using flashcanvas instead of excanvas as the canvas provider for flot. Oh well, we haven’t got anything to lose, right? I replaced the script include and saw – exactly the same thing as before: nothing! (Check out the IE developer toolbar on the right – the you can see the Flash object inside the canvas element that was generated by flashcanvas.)

ie8-flot-flashcanvas

What was left? Oh, I hadn’t tried to check for an updated version of excanvas yet – so I went and did that.

The latest download version dates back to March 2009 but there has been some activity since then so I decide to go for the latest source which is also already a year and a half old but still by a whole year younger that the last official download Smile I replaced the file and haven’t had any problem so far!

We will be keeping an eye on this, but for now my hopes are high that this update might have finally helped.

Happy coding!

Tags: ,

Camping.Info | Design | Web Applikationen | html + css | jQuery

Embed Facebook Like Button – Right Align with css and Settings

by andrej Sun, January 09 2011 18:28

If you want to embed a Facebook Like button and you want it to align to the right here is a fix with css only:

First, get the embed code from facebook: http://developers.facebook.com/docs/reference/plugins/like

If you embed the XFBML code and the button is smaller than the size you specified, the button will always align to the left. There is nothing you really can do about it due to the iframe structure of the embed code.

facebook like button embed left align

However, if you specify the width of the like button to be 0, the iframe will always be almost the size of the button, which means you can align it whichever way you want.

facebook like button right align set with to zero

There in the settings make sure to select width to equal 0. This leads to the facebook like button element always being the size it actually is. Which allows you to position whichever way you want, to the right for example.

However there is one little trick, you still have to pull: There is a 15 pixel margin to the right of the element. You can align the button exactly to the right by giving your parent html element following css style: position:relative; right:-15px;

The result looks like this:

facebook like button right align

Tags:

Tips & Tricks | Design | html + css