views:

52

answers:

3

How would I go about displaying a tooltip when the user hover overs some text / keywords? This body of text is directly retrieved from the database so I am unable to add any span or div tags or title information to these keywords. Is there a way to automatically create tooltips for certain words that are contained in the page?

Please let me know if there are any good tutorials available on how to solve this problem.

+3  A: 
// Create tooltips dictionary
$tooltips = Array("Word1"=>"This word is word number 1", 
                  "Word2"=>"This word is word number 2");

$content = "Here are Word1 and Word2";
foreach ($tooltips as $word=>$tip){
    $content = preg_replace("/(".$word.")/", "<span title='".$tip."'>$1</span>", $content);
}
echo $content;
opatut
Note that "Word1" and "Word2" are regular expressions that cannot contain "/"
opatut
Thanks for the help. This solution works for me. This is also the most efficient solution I found.
Mowgli
+1  A: 

Actually you can make use of span or whatever.

You have two options, the first is load the tooltip content at the first page request in a 'display: none' div or span, and then just show it up with an onmouseover event.

The second option is to perform an ajax request.

You should take a look at this: http://www.smashingmagazine.com/2007/06/12/tooltips-scripts-ajax-javascript-css-dhtml/

Keyne
+2  A: 

I had to do this a while ago. Actually I answered a similar question here: http://stackoverflow.com/questions/1972515/javascript-find-strings-in-dom-and-emphasize-it/1972664#1972664 (took me a while to search for it).

Here's what I use to do the dynamic tooltip thing:

// keyword : tooltip
keywords = {
    'hello world' : 'a common first example program',
    'goodbye cruel world' : 'the opposite of hello world'
};
function insertTooltips (domNode) {
    if (domNode.nodeType === Node.ELEMENT_NODE) { // We only want to scan html elements
        var children = domNode.childNodes;
        for (var i=0;i<children.length;i++) {
            var child = children[i];

            // Filter out unwanted nodes to speed up processing.
            // For example, you can ignore 'SCRIPT' nodes etc.
            if (
                child.nodeName  != 'span' ||
                child.className != 'tooltip_span'
            ) {
                insertTooltips(child); // Recurse!
            }
        }
    }
    else if (domNode.nodeType === Node.TEXT_NODE) { // Process text nodes
        var text = domNode.nodeValue;

        // This is another place where it might be prudent to add filters

        for (var i in keywords) {
          if (keywords.hasOwnProperty(i)) {
            var match = text.indexOf(i); // you may use search instead
            if (match != -1) {
                // This is how you wrap the keyword in a span:

                // create a span:
                var span = document.createElement('SPAN');

                // split text into 3 parts: before, mid and after
                var mid = domNode.splitText(match);
                mid.splitText(i.length);

                // then assign mid part to span
                mid.parentNode.insertBefore(span,mid);
                mid.parentNode.removeChild(mid);
                span.appendChild(mid);

                // now we can assign a mouseover event handler to the span
                span.onmouseover = function(){
                    showToolTip(keywords[i]);
                }

                // give the span a class name to prevent accidental
                // recursion into it:
                span.className = 'tooltip_span';
            }
          }
        }
    }
}

The implementation of the showTooltip function is left as an exercise for the reader.

The idea is basically to use DOM manipulation to dynamically search and wrap the keywords in spans and then assign a mouseover (or mouseclick, up to you) handler to the span to show the tooltip. On my website, the keyword/tooltip hash/object is generated from data pulled out of the database.

This is much more robust than trying to do this using regexp since it prevents accidental processing of words matching the keywords in class name, id and script tags.

slebetman