Google

Tuesday, November 03, 2009

Zero ajax label help tooltips for Apex?

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

A couple of weeks ago i finally managed to complete a quick demo page showing a technique for displaying label tooltips without using Ajax or Javascript.
In practice, this means displaying the help text associated with the page item inside a sort of balloon that pops up whenever the mouse cursor hovers above the label link.
The floating label tooltip is rendered using CSS styles, which means that the whole thing is carried out on the client side, without the need of an extra round trip to the server to get that piece of information.
If we are talking of performance improvements, any technique that saves an additional request to the database should be considered positively.

This technique has been invented by Stuart Nicholls and i merely adapted it for use with Apex, with minor differences.
Stuart's site is very inspiring for anyone who wants to leverage the power of CSS stylesheets to achieve cool visual effects without resorting to the omnipresent javascript and i encourage everyone to have a look at it.

Basically the CSS technique consists in retrieving the help text of all the items involved upfront, format them using certain HTML tags that are matched by rules in the CSS stylesheet.
This at first may seem a contradiction, as i stated that the whole purpose of this was to save a request to the database, but if you compare this to a technique involving Ajax requests, it should be clear the advantage:
with the Ajax approach, a request is sent *every* time the cursor moves over a label link, no matter if the user already did it a few seconds or minutes before, while in the other case, the database request is made using a fast bulk collect statement retrieving all the involved labels in one shot, then it can be rendered as many times as necessary without accessing the db anymore, even if the user moves back and forth from other pages as the content is cached in session state.

Of course there are also a few limitations with this technique which can make it unsuitable for certain situations, for instance it can become unpractical for large texts or when the text contains links that you expect a user to click on. In these situations it makes sense to stick to the Ajax approach, and you could easily mix both on the same page as desired by choosing different label templates. The other major objection to this approach can be in the requirement of creating hidden items to hold the text. Of course it would be much better if we could have a substitution string for retrieving the help text at page rendering time, but i don't know if the Apex team is willing to include the code to support this in a future release.

Given the aforementioned prerequisites, here are the components to get it done in Apex (item names refer to the demo page hosted on apex.oracle.com:

-- before header process, conditional on (P11_ITEM1_HELP is null)
-- the process will run only the first time the page is loaded
-- thereafter values cached in session state will be used.
-- Each item with tooltip needs a hidden item to store the text
-- i.e. P11_ITEM1 is matched by P11_ITEM1_HELP.
declare
type vc2_4k_tab is table of varchar2(4000) index by binary_integer;
type vc2_255_tab is table of varchar2(255) index by binary_integer;
type vc2_coll is table of varchar2(4000) index by varchar2(255);
apex_item_names vc2_255_tab;
apex_item_help_text vc2_4k_tab;
apex_item_help_coll vc2_coll;
begin
select item_name, item_help_text
bulk collect into
apex_item_names, apex_item_help_text
from apex_application_page_items
where application_id = :APP_ID
and page_id = :APP_PAGE_ID
and item_label_template = 'Optional Label with Tooltip';

for i in 1..apex_item_names.count loop
apex_item_help_coll(apex_item_names(i)) := apex_item_help_text(i);
end loop;

:P11_ITEM1_HELP := apex_item_help_coll('P11_ITEM1');
:P11_ITEM2_HELP := apex_item_help_coll('P11_ITEM2');
end;


-- content of the CSS stylesheet (either inline or external)

a.t18tooltip {
text-decoration:none;
font-weight: bold;
}

a.t18tooltip cite {
display:none;
}

a.t18tooltip:hover {
cursor: help;
border:0;
position:relative;
z-index:500;
text-decoration:none;
}

a.t18tooltip:hover cite {
cursor: help;
display:block;
position:absolute;
top:20px;
left:-25px;
padding:5px;
font-weight:normal;
font-style:normal;
color:#000;
border:1px solid #888;
background:#ffc;
width:150px;
text-align: left;
}

a.t18tooltip:hover cite em {
position:absolute;
left:20px;
top:-6px;
width:11px;
height:6px;
background:#fff url(#WORKSPACE_IMAGES#tooltip.gif) 0 0;
display:block;
font-size:1px;
}

<a class="t18tooltip" href="javascript:popupFieldHelp('#CURRENT_ITEM_ID#','&SESSION.')">
Test Item 1<cite><em></em>&P11_ITEM1_HELP.</cite>
</a>


Please note that #WORKSPACE_IMAGES# in the case of Apex with EPG (Embedded PL/SQL Gateway), will generate one db roundtrip. As of Apex 3.1 images in the repository are cached by the browser, however there is still one request to retrieve the E-TAG attribute and compare it with the cached version. If the HTTP server is not EPG, then there won't be any db requests, just a web server request. This tiny image is required to show the nice "spike" pointing to the label, but it can be omitted or perhaps you can dare to implement the second method for rendering CSS tooltips slightly more elaborated to achieve the effects by means of border graphics only.


See more articles about Oracle Application Express or download tools and utilities.

3 comments:

Martin Giffy D'Souza said...

Hi Flavio,

Great post! I noticed that you have to create extra items for each help text. Here's a technique where you don't need to create the hidden help text items: http://apex-smb.blogspot.com/2009/09/tooltip-help-in-apex-alternative-to.html

The only catch is the technique uses JavaScript...

Martin

Byte64 said...

Hi Martin,
i saw the the script, it may come in handy for a "mixed case".

Perhaps one could use the APEX_UTIL.HIDDEN API to automatically create the hidden items basing on the name of the items associated with the tooltip template, a sort of variation of the script i supplied to seed the help text.

I didn't test this possibility, may be it's worth trying later.

Thank you!
Flavio

Mamun said...

nice

http://oracletheworld.blogspot.com/

latest articles

yes you can!

Did you find here a solution to your problem? Did you learn something new? Maintaining Oraclequirks is a time consuming task and resources are required to keep it growing. You can help us out with a minimal effort.
We appreciate your support!
If you can't find the posting being referred in the web search results, it's very likely that it has been already archived.
Check out the blog archive or the index and you will certainly find the related article.