This week's book giveaway is in the Kotlin forum.
We're giving away four copies of Kotlin in Action and have Dmitry Jemerov & Svetlana Isakova on-line!
See this thread for details.
Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Getting null value when trying to use variable value for id attribute  RSS feed

 
Colm McHugh
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I would like to use a variable value for the id of my components. That is, use:

<h:panelGrid id="unique_id_#{bean.value}" rendered="#{bean.boolValue}" >
<!-- stuff -->
</h:panelGrid>

instead of:
<h:panelGrid id="unique_id"

But, even though I can trace the call to bean.value, the value assigned to the id is: unique_id_

I'm expecting it to be something like unique_id_1123. Also If I try id="#{bean.value}" , the app server (Glassfish) gives error: javax.servlet.ServletException: Empty id attribute is not allowed

The other attributes in the component that use the bean behave as expected, such as the rendered attribute.
But, Im guessing, the id value is getting computed before bean is assigned. Are there any special rules about when id attribute values are evaluated?

Notes:
The h:panelGrid component is within a ui:repeat component, which assigns the bean from a list of Java beans.
I'm using JSF core, facelets, html as well as the primefaces component library.

Hope this is clear (??) Let me know if not, or if I can provide more detail.

And many thanks for any tips/advice.
Colm.
 
Tim Holloway
Bartender
Posts: 18713
71
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When in doubt, RTFM: http://download.oracle.com/javaee/5/javaserverfaces/1.2/docs/tlddocs/h/panelGrid.html

Notice that most of the attributes are of type " javax.el.ValueExpression ". That means that you can use EL expressions.

Unfortunately for you, id is "java.lang.String". Which means you're out of luck.

However, I have done something similar for Facelets included components. The EL processor for open text can construct IDs. The way I did it was to supply a param name/value as part of the ui:include. So instead of id="unique_id_#{bean.property}", I coded id="save_#{myparam}".

One thing you should consider, however. JSF works on the concept of naming containers. An h:form is a naming container, as is an h:datatable. At the JSF level, you can use the simple ID to reference objects within the naming container. At the JavaScript and CSS level, you have to use the fully-qualified id, which is the concatenated name of the object and its parents - for example: "form1:table_x:3:username". The "3" is the row index, so that each row object has a unique ID.

Cooking up IDs from symbolic expressions is rarely necessary.
 
Colm McHugh
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Tim, that's really helpful. My motivation for using the variable in setting id name was to ensure the component had a unique id. But, based on naming containers, it sounds like that's not necessary, because, in the context of a loop, the ids for these panelGrid component(s) will be things like "form1:table_x:1:id", "form1:table_x:2:id", "form1:table_x:3:id", etc, and referring to the id in another component should resolve fine, as long as we're at the same container/scope:

<ui:repeat var="bean" values="#{controller.values}">
<h:panelGrid id="id" rendered="#{bean.boolValue}" >
<!-- stuff -->
</h:panelGrid>
</ui:repeat>

I'll test and see.

Thanks,
Colm.
 
Colm McHugh
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I've managed to remove expression evaluation from my id attribute values, but there's one situation I think I need it...
I have a depedent field whose content values comes from two other fields. One of these other fields is in the same scope (loop iteration) so id can be resolved fine when updating it's content from that field, but the other field is in a different scope (loop iteration) so the question remains, how to update my dependent field content when that field value changes?

I've thought about forcing the user to make the dependent field visible after they have populated the two dependent-on fields (and disabling input to the two dependent-on fields to ensure that the user doesn't edit them again to ensure consistency with values in the dependent field). But that feels like it's complicating the architecture of the UI when what I want is to just have dependent field values automatically re-populated when either or both of the two dependent-on field values change... Anyone faced a similar issue before?

Thanks,
Colm.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!