Reputation: 11497
How to attach a rich:tooltip
to the list generated by f:selectItems
when using a variable for the attribute for
inside the rich:tooltip
.
This code works fine (the value of #{prefix}
is theprefixvalue
<ui:composition>
<a4j:form id="#{prefix}_form">
<h:selectOneRadio style="text-align:left" id="#{prefix}_rating">
<f:selectItems value="#{test.options}"></f:selectItems>
</h:selectOneRadio>
<rich:toolTip for="theprefixvalue_form\:theprefixvalue_rating\:0">a</rich:toolTip>
</a4j:form>
</ui:composition>
But this code does not:
<ui:composition>
<h:outputText value="#{prefix}" />
<a4j:form id="#{prefix}_form">
<h:selectOneRadio style="text-align:left" id="#{prefix}_rating">
<f:selectItems value="#{test.options}"></f:selectItems>
</h:selectOneRadio>
<rich:toolTip for="#{prefix}_form\:#{prefix}_rating\:0">a</rich:toolTip>
</a4j:form>
</ui:composition>
Throws the following exception:
Caused by: java.lang.IllegalArgumentException: theprefixvalue_rating
at javax.faces.component.UIComponentBase.findComponent(UIComponentBase.java:612)
at org.ajax4jsf.renderkit.RendererUtils.findComponentFor(RendererUtils.java:1037)
at org.richfaces.renderkit.html.ToolTipRenderer.getTargetId(ToolTipRenderer.java:234)
at org.richfaces.renderkit.html.ToolTipRenderer.constructJSVariable(ToolTipRenderer.java:251)
...
TestBean is session scoped and this is the code for getOptions();
public List<SelectItem> getOptions(){
List<SelectItem> options = new ArrayList<SelectItem>();
options.add(new SelectItem("a","a"));
options.add(new SelectItem("b","b"));
options.add(new SelectItem("c","c"));
return options;
}
Any ideas? The goal is to have a tooltip when the mouse is over the different options. Thanks in advance.
Edit: Apparently HtmlSelectOneRadio
is not implementing NamingContainer
, so it fails at UIComponentBase
line 611:
(result
is an instance of HtmlSelectOneRadio
, length>0
and segments[1] = "theprefixvalue_rating"
)
if (result != null && (!(result instanceof NamingContainer)) && length > 0) {
throw new IllegalArgumentException(segments[i]);
I am trying to use my own NamedHtmlSelectOneRadio
which extends HtmlSelectOneRadio
and implements NamingContainer
but I'm still guessing how to inject it with facelets. Any idea?
Upvotes: 1
Views: 5438
Reputation: 11497
Finally I managed to solve it.
I created my own component called NamedHtmlSelectOneRadio
which is just a wrapper of HtmlSelectOneRadio
but implements NamingContainer
. I don't know if this will have further implications through the rest of JSF code, but my testcase works fine. Anyway, I'll update this answer if I find any strange behavior, as well as I'll post in the Mojarra implementation of JSF regarding why HtmlSelectOneRadi
o does not implements NamingContainer
out-of-the-box.
Here are the steps to create your own component with facelets.
1 Wrap the class:
import javax.faces.component.NamingContainer; import javax.faces.component.html.HtmlSelectOneRadio;
public class NamedHtmlSelectOneRadio extends HtmlSelectOneRadio implements NamingContainer {
public NamedHtmlSelectOneRadio(){
super();
}
}
2 Wrap the Tag class and set the above class as component Type:
import com.sun.faces.taglib.html_basic.SelectOneRadioTag;
public class NamedHtmlSelectOneRadioTag extends SelectOneRadioTag {
public NamedHtmlSelectOneRadioTag(){
super();
}
@Override
public String getComponentType() {
return "javax.faces.NamedHtmlSelectOneRadio";
}
}
3 Add the component to your faces-config.xml
configuration:
<component>
<component-type> com.eyeprevent.util.NamedHtmlSelectOneRadio </component-type>
<component-class> com.eyeprevent.util.NamedHtmlSelectOneRadio </component-class>
</component>
4 Add the tag to your taglib (mine is functions.taglib.xml). More info about creating your own taglib here
<tag>
<tag-name>namedSelectOneRadio</tag-name>
<component>
<component-type>com.eyeprevent.util.NamedHtmlSelectOneRadio</component-type>
</component>
</tag>`
5 Include the new taglib in your .xhtml (or .jsf) page and replace the h:selectOneRadio
with your own (mine is fnc:namedSelectOneRadio
)
xmlns:fnc="http://eyeprevent.com/fnc"
...
<fnc:namedSelectOneRadio id="#{prefix}_rating">
<f:selectItems value="#{test.options}"></f:selectItems>
</fnc:namedSelectOneRadio>
<rich:toolTip for="#{prefix}_form\:#{prefix}_rating:0">a</rich:toolTip>
And that's all!
Upvotes: 3