Adding Table Row Highlighting to ADF Faces pages

End users of web applications like clarity. They want to know where they are in a page, what the current context of information and their actions is. Next to of course a visually appealing look & feel and a crisp performance. Part of the end user’s satisfaction with the applications we create lies in small details, little things like subtle but helpful and stylish (semi-transparent) tooltips, cat-like navigations and scroll-movement: rapid in a lazy sort of way and visual indication of the current action’s whereabouts.

A simple example of such attractive and helpful visual support of the end user is the highlighting of rows in a table when the user moves the mouse over the rows. Hovering over a row can mean anything from ‘it has my current attention ‘, ‘I may be about to activate it’ to ‘content on the page should be synchronized with the currently hovered row’ and ‘after two seconds of hovering, the row should auto-expand and show all its hidden details’. Whatever the meaning may be, users frequently like the visual highlighting of the ‘current’ row. 

Example of a table with row highlighting:

In ADF Faces, there is no direct support for this highlighting – which by the way is essentially a client side operation that we would not want to burden the server with! All it takes in JavaScript are two simple event handlers on the table row (TR) element: a mouseover that starts highlighting and a mouseout that stops it again. However, the ADF Faces table component does not give us access to the TR element it will render. We can define event handlers for the entire table and for individual cells and column headers and footer.

The desired functionality is still easily added to the ADF Faces tables through ....
a simple post-load operation. Also see the blog article Enhance the web page look & feel and behavior after it has been loaded – attach onLoad Event Listeners during load for more details on post-load operations on webpages.

The approach consists of these steps:

1. line up an ADF Table up for TR-Highlighting by adding a marker-class to its styleClass attribute:

&lt;af:table ....   styleClass=&quot;trhighlighter&quot; .... &gt;<br />&nbsp;

2. add functions highlightTR and dehighlightTR to a JavaScript library attached to the page that contains the table(s) to add highlighting to; these functions will take care of the stylechanges all cells in a selected TR should undergo when highlighted or not highlighted (note: such style changes do no have to be limited to just the background color): 

function highlightTR(){<br />  var allTd = this.parentNode.getElementsByTagName('td');<br />  for(var j=0;j &lt; allTd.length;j++){<br />    var tdObj = allTd[j];<br />    tdObj.style.backgroundColor = 'red'; //'#EFEFEF';<br />    }//for<br />}// highlightTR<br /><br />function dehighlightTR(){<br />  var allTd = this.parentNode.getElementsByTagName('td');<br />  for(var j=0;j &lt; allTd.length;j++){<br />    var tdObj = allTd[j];<br />    tdObj.style.backgroundColor = '';<br />  }//for<br />}//  dehighlightTR<br />&nbsp;

3. add generic event listener adder function

function addAnyEventListener(fn, obj, eventType){<br />    if ( typeof obj.addEventListener !='undefined')    <br />      obj.addEventListener(eventType,fn,false);<br />    else <br />      if (typeof obj.addEventListener !='undefined')    <br />         obj.addEventListener(eventType,fn,false);<br />      else <br />        if ( typeof obj.attachEvent !='undefined')    <br />          obj.attachEvent('on'+eventType,fn);<br />}//addAnyEventListener<br />&nbsp;

4. add function addTRHighlighting to a JavaScript library attached to the page that contains the table(s) to add highlighting to:

function addTRHighlighting() {<br />  // find all divs with class=='trhighlighter'<br />  // their embedded tables are candidates for tr highlighting<br />  var allDiv = document.getElementsByTagName('div');<br />  for(var n=0;n &lt; allDiv.length;n++){<br />    theDiv = allDiv[n];  <br />    if (theDiv.className &amp;&amp; theDiv.className.indexOf('trhighlighter')!=-1) {<br />      var allTbl = theDiv.getElementsByTagName('table');<br />     <br />      for(var m=0;m &lt; allTbl.length;m++){<br />        theTbl = allTbl[m];<br />        // find all TDs in the table<br />        var allTd = theTbl.getElementsByTagName('td');<br />        for(var j=0;j &lt; allTd.length;j++){<br />          // add the mouseout and mouseover event listeners<br />          addAnyEventListener(dehighlightTR, allTd[j], &quot;mouseout&quot;);<br />          addAnyEventListener(highlightTR, allTd[j], &quot;mouseover&quot;);<br />        }        <br />      }//for tbl<br />    }        <br />  }//for div<br /> <br />}//addTRHighlighting()<br />&nbsp;

5. add a call to addTRHighlighting as postload operation

addLoadListener(addTRHighlighting);&nbsp;

 

Note: As with earlier posts using JavaScript, much of the code can be made simpler and probably more robust by leveraging libraries such as jQuery. I have only just started my exploration into jQuery, but it seems enormously promising – as Jeroen has pointed out to me many times. 

  1. Hi,
    The functions highlightTR and dehighlightTR not work in IE7
    I add the next condition:

    if (ev.srcElement){ //for IE
    var allTd = ev.srcElement.parentNode.getElementsByTagName(‘td’);
    }
    else{
    var allTd = this.parentNode.getElementsByTagName(‘td’);}

    Thanks

  2. Good morning.

    Hi, good article. I like a complete application in adf for example. excuse me my English.