PrimeFaces / JSF component id not found from p: datatable

I am just starting with PrimeFaces 3.3.1 coming out of RichFaces 3 and 4.

I have data with structure:

<f:facet name="header"> <h:outputText value="Employees" /> </f:facet> <p:column sortBy="#{emp.lastName}"> <f:facet name="header"> <h:outputText value="Last Name" /> </f:facet> <h:outputText value="#{emp.lastName}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="First Name" /> </f:facet> <h:outputText value="#{emp.firstName}" /> </p:column> ... <p:column> <p:commandButton icon="ui-icon ui-icon-trash" value="Remove" process="@this" update="employee-remove-dialog" oncomplete="employeeRemoveDialog.show();"> <f:setPropertyActionListener target="#{employeeManager.currentEmployee}" value="#{emp}" /> </p:commandButton> </p:column> </p:dataTable> <p:dialog header="Remove Employee" modal="true" appendToBody="true" widgetVar="employeeRemoveDialog" id="employee-remove-dialog"> <h:outputText value="Remove employee #{employeeManager.currentEmployee.fullName}?" /> <f:facet name="footer"> <p:commandButton icon="ui-icon ui-icon-check" value="OK" action="#{employeeManager.deleteEmployee}" process="@this" update="employee-list" oncomplete="employeeRemoveDialog.hide();" /> <p:commandButton icon="ui-icon ui-icon-close" value="Cancel" onclick="employeeRemoveDialog.hide();" ajax="false" immediate="true" /> </f:facet> </p:dialog> </h:form> 

However, PrimeFaces throws an exception:

 09:36:08,961 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost-127.0.0.1-8080-1) Error Rendering View[/employeeList.xhtml]: javax.faces.FacesException: Cannot find component with identifier "employee-remove-dialog" referenced from "j_idt30:employee-list:0:j_idt41". at org.primefaces.util.ComponentUtils.findClientIds(ComponentUtils.java:251) [primefaces-3.3.1.jar:] at org.primefaces.util.AjaxRequestBuilder.addIds(AjaxRequestBuilder.java:102) [primefaces-3.3.1.jar:] at org.primefaces.util.AjaxRequestBuilder.update(AjaxRequestBuilder.java:90) [primefaces-3.3.1.jar:] at org.primefaces.renderkit.CoreRenderer.buildAjaxRequest(CoreRenderer.java:195) [primefaces-3.3.1.jar:] at org.primefaces.component.commandbutton.CommandButtonRenderer.encodeMarkup(CommandButtonRenderer.java:74) [primefaces-3.3.1.jar:] at org.primefaces.component.commandbutton.CommandButtonRenderer.encodeEnd(CommandButtonRenderer.java:49) [primefaces-3.3.1.jar:] at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312) [jsf-impl-2.1.7-jbossorg-2.jar:] at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185) [jsf-impl-2.1.7-jbossorg-2.jar:] at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129) [jsf-impl-2.1.7-jbossorg-2.jar:] at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at org.primefaces.component.datatable.DataTableRenderer.encodeRegularCell(DataTableRenderer.java:780) [primefaces-3.3.1.jar:] at org.primefaces.component.datatable.DataTableRenderer.encodeRow(DataTableRenderer.java:741) [primefaces-3.3.1.jar:] at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:645) [primefaces-3.3.1.jar:] at org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:248) [primefaces-3.3.1.jar:] at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:220) [primefaces-3.3.1.jar:] at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:107) [primefaces-3.3.1.jar:] at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:55) [primefaces-3.3.1.jar:] at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43) [primefaces-3.3.1.jar:] at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51) [primefaces-3.3.1.jar:] at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402) [jsf-impl-2.1.7-jbossorg-2.jar:] at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.7-jbossorg-2.jar:] at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) [jsf-impl-2.1.7-jbossorg-2.jar:] at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:] at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.7-jbossorg-2.jar:] at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:] at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:] at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_04] 

Identifier not found. Hmm .... I basically copied the structure from RichFaces. There, the line button for deleting or editing a line is not needed: employee-form: ... prefixing. I wonder why.

When providing an identifier form and a prefix for links to PF components with the syntax ":", the code works as expected:

  <h:form id="employee-form"> <p:dataTable ...> ... <p:column> <h:panelGrid ...> <p:commandButton ... update=":employee-form:employee-remove-dialog" ...> ... </p:commandButton> </h:panelGrid> </p:column> </p:dataTable> <p:dialog ... id="employee-remove-dialog"> </p:dialog> </h:form> 

IN:

Why is p: datatable required to prefix JSF root identifiers? Maybe this is my code, but the presented example seems to me minimal. In any case, using this will result in possibly long identifiers throughout the application.

What am I doing wrong?

PS: I'm on JBoss AS 7.1.1. Final, Mojarra 2.1.7, PF 3.3.1

+6
source share
1 answer

PrimeFaces uses the standard JSF algorithm provided by UIComponent#findComponent() to find components using this client identifier. The algorithm is described in detail in the previous javadoc. Here's an excerpt of relevance:

A search expression consists of either an identifier (which exactly matches the id of the UIComponent , or a series of identifiers associated with the UINamingContainer#getSeparatorChar character value). The search algorithm should act as follows; alternative algorithms can be used until the end result is as follows:

  • Define the UIComponent that will be the base for the search by stopping as soon as one of the following conditions is true:
    • If the search expression begins with a delimiter character (called the "absolute" search expression), the base will be the root of the UIComponent of the component tree. The leading delimiter character will be deleted, and the remainder of the search expression will be treated as a “relative” search expression, as described below.
    • Otherwise, if this UIComponent is a NamingContainer , it will serve as the foundation.
    • Otherwise, search for the parents of this component. If a NamingContainer , this will be the base.
    • Otherwise (if NamingContainer is not found), the UIComponent root will be the base.
  • The search expression (possibly modified in the previous step) is now a “relative” search expression that will be used to search for the component (if any) that has an identifier that matches within the base component. The match is performed as follows:
    • If the search expression is a simple identifier, this value is compared with the id property, and then recursively through the faces and children of the UIComponent base (in addition, if the found NamingContainer descendant NamingContainer found, its own faces and children were not searched).
    • If the search expression contains more than one identifier separated by a separator character, then the first identifier is used to determine the location of the NamingContainer according to the rules at the previous marker point. Next, the findComponent() method of this NamingContainer will be called, passing the rest of the search expression.

RichFaces uses the same "with some additional exceptions" algorithm.

"reRender" uses the UIComponent.findComponent() algorithm (with some additional exceptions) to find the component in the component tree.

These additional exceptions are not described in detail anywhere, but it is well known that relative component identifiers (i.e. those that do not start with : are not only viewed in the context of the closest parent of the NamingContainer , but also in all other NamingContainer components in one view ( which, incidentally, is a relatively expensive task).

+13
source

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


All Articles