Hi Simon and Andrew,
Thanks for the excellent advice. The <f:attribute> type of tag sounds like the right way to go, especially coupled with modification suggested on the response writer. I'll probably try to hack that in, assuming that <f:attribute> can be used with tags beside UICommand. If it can't then I guess I'll have to create a new component that does the same, but with any subclass of UIComponent.
In JSF in Action I think Kito recommended creating a HTMLRenderer parent class that has a
utility method for rendering the UIComponent.attributes list / the pass through
attributes. Do you know if myfaces has something like this built in...that could be
turned on via configuration. This would save the renderer implementation as well. To be
safe I'm thinking it should be handled at the tag level. So if the component tag had a
renderPassThroughAttributes="true", then the renderer would render the pass
through attributes. Otherwise, we would get the current default behavior. Thoughts?
Thanks again,
- Ole
simon wrote:
On Fri, 2007-12-14 at 20:07 -0600, Ole Ersoy wrote:
Hi,
I have a attribute that I just need to get passed through to the corresponding
html element. For example:
<h:form id="registrationForm"
anAdditionalAttribute="I need to get through to the form element">
</h:form>
In the rendered output I would like:
<form
...
anAdditionalAttribute="I need to get through to the form element">
</form>
I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass. Then subclass the corresponding renderer and render this attribute.
Does anyone know if there's a quicker/magic way to get the job done?
Every component has an "attributes" property that is a map that anything
can be stored in. It is common for properties that are not used by the
component itself (just the renderer) to be stored in this map, rather
than be on the component. The renderer can then retrieve them by:
component.getAttributes().get("anAdditionalAttribute");
So that saves subclassing the component...
But the hard part is that to allow the tag to accept another attribute,
you need to subclass the tag class, and create a new taglib. Then your
page will need to use
<foo:form ...>
rather than
<h:form ...>
An alternative would be to write a custom tag that can be used to store
values into the attributes map of its enclosing component. Then
something like:
<h:form ....>
<foo:attribute name="anAdditionalAttribute" value="I need.."/>
could be used rather than creating a special tag for it.
As it happens, in MyFaces the standard f:attribute tag currently does
exactly this. Interestingly, it possibly shouldn't: the official JSF
docs say that it should only affect:
"the closest parent UIComponent custom action"
which I guess means it should walk up the component tree to find a
subclass of UICommand. I'll investigate what the Sun RI implementation
does...
If using f:attribute is acceptable to you, that avoids creating a new
tag class too, leaving just the renderer code to be done.
Regards,
Simon