• Home
  • About
  • Doom II
  • Flog
  • Inspiration

RichFaces #{rich:element()} Workaround

Posted in Computing. on Thursday, November 17th, 2011 by Derek
Nov 17

Working with the Seam Framework and RichFaces for over a year, I found their components work in the general case. i.e., the simplest of early oughts HTML forms. But complex AJAX views cause all sorts of difficulties once you get into EL expressions for iterated components (e.g., from <rich:datatable>) within <f:subview>-named scopes.

The biggest challenge has been to get each customized component instance to display and behave correctly within the same view, avoiding situations where the rendered=”" attribute doesn’t evaluate to the expected value (as elements are still in the component tree when rendered=”false”.) For example, the <c:if> test=”" expression is evaluated when the component tree is built, so if any variables within test=”" reference a render-time component such as var=”" of <rich:datatable>, that EL statement may evaulate to null or false. Do not use <c:if> nested in an iterated component like <rich:datatable>. It will only cause hands to be thrown up in the air with disgust.

Another big problem is RichFaces’ rich:element() function not taking namespace into consideration, so the nearest id=”" component-matching sibling or even first match in the whole view will be returned. A parent <f:subview> will not be used unless you explicitly prefix the rich:element() parameter with it.

<f:subview id="mySubview">
<h:inputtext id="myInput" />
<h:graphicimage value="img.png" onclick="#{rich:element('mySubview:myInput').focus()" />
</f:subview>

The issue I had was <f:subview> instances used in customized components, where I would have to require an id=”" attribute to be defined for every usage of components. e.g., <customlibrary:customtag id=”yourComponentId” …/>. This is just tag soup and kinda amateur hour.

I found the best workaround was a JavaScript hack that takes into account how JSF generates the HTML markup of id=”" attributes on each DOM element sourced from the component tree. It is the clientId of each JSF component in the tree concatenated by the ‘:’ character. By truncating up to the last ‘:’, you can attain the parent subview and then append the string parameter usually passed into rich:element() or rich:component(). For example, the oncomplete=”" attribute of <a4j:commandbutton>, the previous method to attain a local DOM reference:

var domObj = #{rich:element('yourComponentId')};

becomes:

var domObj = document.getElementById(this.id.substring(0, this.id.lastIndexOf(':')) + ':yourComponentId');

And that fixes all the wonkiness with changing visibility or using JQuery animations to manipulate JSF components in a contemporary manner. I mean, really RichFaces.

  • Now Playing: Fair to Midland - Fables From a Mayfly: What I Tell You Three Times is True - 04 - The Wife, The Kids, and The White Picket Fence

Leave a Reply

CAPTCHA Image
Refresh Image
*

Derek MacDonald


  • Photo Stream
  • Categories
    • Australia
    • Computing
    • Film & TV
    • Food
    • Gaming
    • General
    • Music
    • Sports
    • Visual Art
  • Search






  • Home
  • About
  • Doom II
  • Flog
  • Inspiration

© Copyright Derek MacDonald. All rights reserved.
Designed by FTL Wordpress Themes brought to you by Smashing Magazine

Back to Top