I try to make the two component components fit well together, inserting them as a child. The setting consists of a lightbox and input with the "Value" attribute. This works fine until I have a number of inputs and therefore should use ui: repeat.
bugTest.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:pw="http://java.sun.com/jsf/composite/components"> <h:head></h:head> <h:body> <pw:lightBox value="Header"> <h:form> <ui:repeat var="input" value="#{BugTestBean.inputs}"> <pw:bugTestInput value="#{input}" /> </ui:repeat> </h:form> </pw:lightBox> </h:body> </html>
It seems that ui: repeat gets the value attribute of the two components, and the following exception is thrown.
Caused by: javax.el.PropertyNotFoundException: /resources/components/bugTestInput.xhtml @15,62 value="#{cc.attrs.value.text}": The class 'java.lang.String' does not have the property 'text'. at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111) at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) at javax.faces.component.UIOutput.getValue(UIOutput.java:170) at javax.faces.component.UIInput.getValue(UIInput.java:284) at com.sun.faces.facelets.component.UIRepeat$SavedState.populate(UIRepeat.java:879) at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:396) at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:402) at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:402) at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:356) at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:470) at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:586) at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1042) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819) at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847) at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304) at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105) at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847) at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304) at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105) at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819) at com.sun.faces.renderkit.html_basic.CompositeRenderer.encodeChildren(CompositeRenderer.java:78) at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822) at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:447) at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:159) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) ... 33 more
It seems that the lightbox value is being passed to the inputs.
welded the example to a minimum to cause an error.
I tried Mojarra 2.1.26 and 2.2.4.
BugTestBean.java
@ManagedBean(name="BugTestBean") @ViewScoped public class BugTestBean { private List<BugTestInput> inputs; public BugTestBean() { inputs = new ArrayList<BugTestInput>(); inputs.add(new BugTestInput("Test1")); inputs.add(new BugTestInput("Test2")); inputs.add(new BugTestInput("Test3")); inputs.add(new BugTestInput("Test4")); } public List<BugTestInput> getInputs() { return inputs; } }
bugTestInput.xhtml
<cc:interface> <cc:attribute name="value" /> </cc:interface> <cc:implementation> <div id="#{cc.clientId}"> <h:inputText id="input" value="#{cc.attrs.value.text}" /> </div> </cc:implementation>
BugTestInput.java
public class BugTestInput { private String text; public BugTestInput(String text) { this.text = text; } public String getText() { return text; } public void setText(String text) { this.text = text; } }
lightbox.xhtml
<cc:interface> <cc:attribute name="value" /> </cc:interface> <cc:implementation> <div id="#{cc.clientId}"> <h:outputText value="#{cc.attrs.value}" /> <h:panelGroup> <cc:insertChildren /> </h:panelGroup> </div> </cc:implementation>
Current solutions
Renaming the attribute value to something else in the lightbox fixes this problem.
Remaining the attribute value, empty on the lightbox, also works.
Not using ui: repeat will also fix the problem, but it is not difficult.
Currently I use 2 attributes per lightbox and leave the value blank if necessary
<h:outputText value="#{cc.attrs.value}#{cc.attrs.title}" />
Subsequent actions No matter what the attribute name is, if they are the same for both components, this will not work. Whether this is a bug in JSF, I looked for traces of errors and most new patches without result.