Composite components with composite children mixing values โ€‹โ€‹when used with ui: repeat

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.

+6
source share
1 answer

Have you tried using the <c:forEach> in JSTL instead of <ui:repeat> ? I have always encountered problems with the <ui:repeat> .

<c:forEach> should work unless you re-render the component using ajax calls.

0
source

Source: https://habr.com/ru/post/955768/


All Articles