Email This Post Email This Post Print This Post Print This Post

Tooltips for Forms

Wed, Oct 17, 2007 – 2:25 pm

Create a tooltip for you web forms !

A tooltip is a small box containing which appears when you move your mouse over a hyperlink:
Hover over me to see

This visual element is useful in supplying additional information to the user without needing to take up addtional space on the screen. It is very easy to implement as well. All you need do is to use the “title” property of the anchor tag to display the addtional text message:

<a href="#" title="This is a standard tooltip">Hover over me to see</a>

One problem with the standard tooltip is that you can’t control how long the tool tip stays visible so you are limited to using very short messages.

Another problem is that using “title” in other HTML elements, such as an INPUT tag for a form, the implementation is not exactly what you would want to happen. It shows up if the user thinks to “hover” the mouse over the input field, but will not show up if they simply tab into it or move their mouse to another area of the screen.

That’s too bad because a forms input tag is the perfect place to have a tooltip. It could be used as a mini-help note. Letting the user know what the field is for, what format is expected, etc..

Since I do a lot of web development for data entry work I thought it would be a good idea to come up with a tooltip function that would work easily with a form, let me leave little helpful notes for the user, and one where I could control how long the tooltip would remain visible on the screen so longer messages could be left.

Note: In the below code I am using the FindPosition function to find the position of an object. I’ve included it here, but more information can be found about that function in the Finding the Position of an object article on this site.

To use the tool tip simply call it from the input tag of your form when focus is set to it

Example:

<form>
<input value="click here" onfocus="tooltips('Display a tool tip.');" type="text">
<input value="tab to here" onfocus="tooltips('Display a longer tooltip for 30 seconds. ',30);" type="text">
</form>

Function:

tooltips.js
tooltips demo page

// *****************************************************************************
// ** tooltips.js
// **
// ** Unobtrusive JavaScript function which will display a tool tip when called
// **
// ** Author: Stan Slaughter
// ** Web: http://www.StanSight.Com/
// *****************************************************************************

  //////////////////////////////////////////////////////////////////////////////
  // tooltips - Find object which called tooltip then show the tooltip message
  //  @param msg - Message to display
  //  @param displayseconds - *Optional* Number of seconds to display the tool tip
  //  @return void
  //////////////////////////////////////////////////////////////////////////////
  function tooltips(msg,displayseconds) {

    // Get object reference to element which triggered this event
    var event = (this.event) ? this.event : tooltips.caller.arguments[0] || window.event;
    var obj = event.target ? event.target : event.srcElement;

    // If not passed in set the default value for the optional displayseconds parameter
    displayseconds = (typeof(displayseconds)=="undefined") ? 10 : displayseconds;

    // Show Tooltip
    showTooltips(obj,msg,displayseconds)
  }

  //////////////////////////////////////////////////////////////////////////////
  // showTooltips - Function to display a tool tip.
  //  @param obj - Object to display the tool tip for
  //  @param msg - Message to display
  //  @param displayseconds - Number of seconds to display the tool tip
  //  @return void
  //////////////////////////////////////////////////////////////////////////////

  var HideTipTimer = 0;
  function showTooltips(obj,msg,displayseconds) {

    // Figure out where the input field object is on the screen by adding
    // up all the offsets for all the containing parent objects
    var obj_pos = FindPosition(obj);
    var tip_left = obj_pos[0];
    var tip_top = obj_pos[1];

    // Add obj height to top position so tip box DIV will show up underneath "obj"
    tip_top += obj.offsetHeight;

    // Create DIV tag object through DOM to hold the "tip" message (if it does not already exist)
    if (document.getElementById("tip") == null) {

      // Create tip box DIV
      tipdiv = document.createElement("div");
      document.body.appendChild(tipdiv);
      tipdiv.setAttribute("id", "tip");

      // Format appearance of tip box DIV (Note: could have just used a CSS
      // class, but I wanted to make this idependent of external files)
      tipdiv.style.zIndex = "500";
      tipdiv.style.position = "absolute";
      tipdiv.style.fontFamily = "Arial";
      tipdiv.style.color = "black";
      tipdiv.style.backgroundColor = "#FFFFE6";
      tipdiv.style.border = "1px solid #7F7F7F";
      tipdiv.style.padding = "0px";
      tipdiv.style.textAlign = "left";
      tipdiv.style.cursor = "pointer";

      // Create Paragraph to hold message contents
      tipdivP = document.createElement("p");
      tipdiv.appendChild(tipdivP);
      tipdivP.setAttribute("id", "tipP");
      tipdivP.style.margin = "8px";

      // Create shadow tip box
      shadowdiv = document.createElement("div");
      shadowdiv.setAttribute("id", "shadowTip");
      document.body.appendChild(shadowdiv);

      // Format appearance of shadow tip box (Note: could have just used a CSS
      // class, but I wanted to make this idependent of external files)
      shadowdiv.style.zIndex = "499";
      shadowdiv.style.position = "absolute";
      shadowdiv.style.opacity = ".5";
      shadowdiv.style.backgroundColor = "#DFDFDF";
      shadowdiv.style.border = "2px solid #EFEFEF";
      shadowdiv.innerHTML = "&nbsp;"

      // Allow a click on the "tip" div to hide the message.
      tipdiv.onclick = function (aEvent){
        document.getElementById("shadowTip").style.display="none";
        document.getElementById("tip").style.display="none";
      }

    } else {
      // Div Tag allready esists, clear out old timer then get reference to tip box
      clearTimeout(HideTipTimer);
      tipdiv = document.getElementById("tip");
      tipdiv.style.display="none"; // Hide any old message

      tipdivP = document.getElementById("tipP");
      tipdivP.innerHTML = "";

      shadowdiv = document.getElementById("shadowTip");
      shadowdiv.style.display="none";
    }

    // Roughly figure how how wide to make tip box DIV based on the number
    // of characters in the message. If max width is exceeded then just use max width
    var iFontSize = 10;
    var iCharWidth = iFontSize / 2; // Assume characters are half as wide as they are tall
    var iMaxWidth = 350;
    var iNumChars = msg.length;
    var tip_width = (iNumChars * iCharWidth + 6 > iMaxWidth ) ? iMaxWidth : iNumChars * iCharWidth + 6;

    // Set tip box width and font size
    tipdiv.style.width  = tip_width + "px";
    tipdiv.style.fontSize = iFontSize + "px";

    // If message is not empty then postion and show tip box
    var display_type = "none";
    if (msg != "") {
      display_type = "block";      

      // Assign the message to the tip box
      tipdivP.innerHTML = msg;
      var tipdivWidth = parseInt(tipdiv.style.width);

      // Keep tip box from running off right of screen
      var widthPad = 25; // scroll bar and shadow offset
      if (tip_left + widthPad + tipdivWidth > document.body.offsetWidth) {
        var diff = (tip_left + widthPad + tipdivWidth) - document.body.offsetWidth;
        tip_left -= diff;
      }

      // Position tip box DIV
      tipdiv.style.top = tip_top + "px";
      tipdiv.style.left = tip_left + "px";

      // Position shadow DIV
      shadowdiv.style.top = (2 + tip_top) + "px";
      shadowdiv.style.left = (4 + tip_left) + "px";

      // Show tip box and shadow
      tipdiv.style.display = display_type;
      shadowdiv.style.display = display_type;

      // Set shadows width and height based in tip box *after* message is assigned
      shadowdiv.style.width = tipdivWidth + "px";
      shadowdiv.style.height = (tipdiv.offsetHeight + 2) + "px";

      // If tip is being displayed then wait 'displayseconds' seconds then
      // hide the tip box DIV
      if (display_type == "block") {
        var hideTipCmd = 'document.getElementById("shadowTip").style.display="none";' +
                         'document.getElementById("tip").style.display="none";';
        displayseconds = displayseconds * 1000;
        HideTipTimer = setTimeout(hideTipCmd,displayseconds);
      }
    }

  }

  //////////////////////////////////////////////////////////////////////////////
  // FindPosition - find the Top and Left postion of an object on the page
  //  @param obj - object of element whose position needs to be found
  //  @return array - Array whoose first eleemnt is the left postion and whoose
  //                  second is the top position
  //////////////////////////////////////////////////////////////////////////////

  function FindPosition(obj) {
    // Figure out where the obj object is in the page by adding
    // up all the offsets for all the containing parent objects
    if (obj == null) return [0,0];

    // Assign the obj object to a temp variable
    tmpObj = obj;

    // Get the offsets for the current object
    var obj_left = tmpObj.offsetLeft;
    var obj_top = tmpObj.offsetTop;

    // If the current object has a parent (ie contained in a table, div, etc..)
    if (tmpObj.offsetParent) {

      // Loop through all the parents and add up their offsets
      // The while loop will end when no more parents exist and a null is returned
      while (tmpObj = tmpObj.offsetParent) {
      	obj_left += tmpObj.offsetLeft;
      	obj_top += tmpObj.offsetTop;
      }
    }
    return [obj_left , obj_top];
  }
  1. 15 Responses to “Tooltips for Forms”

  2. I added on line 28 this code(and it works):
    tipdiv.onclick = function (aEvent){this.style.display=”none”;};
    stan sight
    you know what it does.
    thanks

    By jamSoft on Apr 2, 2008

  3. Nice addition jamSoft.

    It lets the user click on the tip box to dismiss it. It makes larger values for displayseconds more practical.

    By Stan Slaughter on Apr 2, 2008

  4. This isnt working for me. I am getting “error on page” when I click on the INPUT box.
    I have the INPUT fields in the form embedded in a TABLE, could this be confusing things?
    (I tried IE7 and Firefox3)

    By Garfy on Jul 24, 2008

  5. I noticed an error this morning myself. :)

    I’ve updated the code, but it was on line 29

    tipdiv.onclick = function (aEvent){this.style.display=”none”;};

    The quotes around the word “none” were not valid quote marks (they were some sort of invalid encoded character).

    Try this new version and see if it works better for you.

    P.S.

    I went a head and included the FindPosition function in here so you will not need to go hunting for it.

    By Stan Slaughter on Jul 24, 2008

  6. Am using Tooltips script but am gettingerror message:

    missing ; before statement
    [Break on this error] 16. function Tooltips(msg,displayseconds) { \n

    Any ideas what I am doing wrong?

    By Marten Gallagher on Feb 23, 2009

  7. Am getting this eror:

    missing ; before statement
    16. function Tooltips(msg,displayseconds) { \n

    What might I have done wrong?

    By Marten Gallagher on Feb 23, 2009

  8. Martin,

    With out seeing how your are using it, I’m not sure if I can help – but does your “msg” contain single or double quote marks ?

    Also were you using IE8 ? I’ve not tested it against that yet.

    By Stan Slaughter on Feb 23, 2009

  9. I have just worked it out and I am so embarrassed! I had copied from the web page and included all the line numbers!

    Aaarrgghh!

    But while you’re there…I want to do all the styling outside in an external css file…so have been trying to comment out the css style lines but it gets a bit tangled with the size of the box calculation bit. How would I go about setting the width to a fixed width and the allowing it to adjust the height normnallylike any block of html?

    By Marten Gallagher on Feb 23, 2009

  10. Oh and for information it works on IE8/XP and in IE8/Windows 7 and in Chrome/XP and Chrome/Windows 7

    By Marten Gallagher on Feb 23, 2009

  11. Oh, and Firefox/Mac OSX 10.4.11 and Safari/Mac OSX 10.4.11

    By Marten Gallagher on Feb 23, 2009

  12. “How would I go about setting the width to a fixed width”

    Change line 114

    from this:

    “var tip_width = (iNumChars * iCharWidth + 6 > iMaxWidth ) ? iMaxWidth : iNumChars * iCharWidth + 6;”

    to this:

    “var tip_width = XXXX”

    Where XXXX is the fixed width you want it to be.

    By Stan Slaughter on Feb 23, 2009

  13. And one last query – is itpossible to change something somewhere so the offset is to the right or to the left rather thannunderneath.A drop-down box obscures the tooltip.

    http://www.martengallagher.co.uk/experimenting/form.html

    Section 02 – hover over 02a1 red
    or
    Section 06 – hover over ‘Which building material do you prefer?’

    These would be places where the better ofset might be to the left of the origin. Any thoughts?

    Am very impressed with it thus far and am hoping to build it into my ‘search for the definitive form’ of which that page is the experimental base.

    By Marten Gallagher on Feb 23, 2009

  14. Glad you are finding it of some use. I tried to design it so it would be easy for any to customize and change the code to suit their needs. (One of the reasons there are almost as many comments as there is code :) )

    To make the tip appear to the right you need to just add the width of the form element to the tip_left position. You would do this under the current line 47. So this:

    // Add obj height to top position so tip box DIV will show up underneath “obj”
    tip_top += obj.offsetHeight;

    would become this:

    // Add obj height and width so tip box will show up underneath and to the right of “obj”
    tip_top += obj.offsetHeight;
    tip_left += obj.offsetWidth;

    By Stan Slaughter on Feb 24, 2009

  15. Thanks – I am not a programmner but am a logical person so I managed to fiddle and add three variables to the htmlcode part so that the tooltip can be thrown aroudn anywhere.

    My next step is to get it to draw messages from a standard bank of messages in a textfile. Will keep you posted.

    And yes you are right – the detialed comments helped a non-programmer sort through it logically.

    Latest incarnation:
    http://www.martengallagher.co.uk/css/tooltips.js

    By Marten Gallagher on Feb 24, 2009

  16. I found this site using [url=http://google.com]google.com[/url] And i want to thank you for your work. You have done really very good site. Great work, great site! Thank you!

    Sorry for offtopic

    By Irradcacifs on Nov 12, 2009

Post a Comment