June 24, 2008

Javascript again (or getting tooltips to work with Scriptaculous Sortables)

Tags: Javascript, Projects, Technical

Update: based on the work I detail here I have created my own Javascript tooltip library based on Prototype.

Over a decade ago Borland had an IDE called Intrabuilder, which allowed you to create websites in a Visual Basic like manner using Javascript on the server. After leaving postgrad study I worked at a now defunct dot.com called Electrolley for 9 months using this tool to create an online grocery store. Serverside javascript was an idea well ahead of its time. Indeed, javascript on the client side in 1997 was crap too. Now javascript is cool and moving forward (backwards?). With my new project, I need to return to Javascript and the last couple of days have been a hard reintroduction.

I am using Prototype and Scriptaculous to make my website as easy to use as possible. I also found some random code on the web to do tooltips - it almost worked! Applying tooltips to Scriptaculous Sortable elements leads to many problems, and I have just finished largely rewriting the library.

  • After moving some sortable elements the tooltips of the moved elements would be displayed underneath the unmoved elements. This is because of the way z-index stacking contexts are created in browsers. In moving an element, Scriptacolous clones it and moves the clone, inserting a new element when the element is dropped. This causes the dropped item to be in a different z-index stacking context than the other items. To get around this, the tooltips need to be drawn outside the moved elements context. This can be done by cloning the tooltip and then inserting it into the document at a point outside the sortable elements’ container. I have explicitly put in the id’s to which the tooltips is being attached, they should probably be passed in (left as an exercise for the reader).
this._clone = this.tool_tip.cloneNode(true);
$("container").insertBefore(this._clone, $("main_content"));

When the tooltip needs to be hidden, just destroy the clone:

Element.remove(this._clone);
this._clone = null;
  • This also means the tooltip needs to be positioned absolutely, so ensure you are using absolute screen x & y coordinates.
  • Dragging a sortable element over other elements results in a number of mouse events firing as the elements are redrawn. Many of these events are consumed by Scriptaculous and not passed on. Thus, the tooltips hide and show functions may be called in any order, resulting in spurious and permanent copies (since it is cloned) of the tooltip all over the screen. To get around this just ensure there is only ever once tooltip on the screen at a time, so at the top of the show method put
if (this._clone) {
   hideTooltip(event)
}

It seems simple now I’ve fixed the problems, but it took a couple of days to remember my old Javascript knowledge.