Duplicate component identifier in JSF using compound component twice in view

I โ€œinheritedโ€ the JSF 2 application (JSF 2.2.7) in my company and ran into java.lang.IllegalStateException because the two components seem to have the same identifier.

The structure of the presentation is as follows (I extracted the appropriate code for illustration, it may contain some typos / invalid syntax when I changed some names):

<p:commandButton id="editButton" action="#{controller.prepareItem()}" update=":itemEditDlg" oncomplete="PF('itemtEditDlg').show()" /> <comp:editItemDlg id="itemEditDlg" /> <p:dialog id="anotherDlg" > <h:form id="anotherForm"> <c:forEach items="#{controller.allArgs}" var="arg" > <!-- next line is the problem --> <comp:mycomponent arg="#{arg}" /> </c:forEach> </h:form> </p:dialog> 

mycomponent.xhtml is as follows:

 <cc:interface> <cc:attribute name="arg" required="true" /> </cc:interface> <cc:implementation> <p:inputText id="argValue" value="#{cc.attrs.arg}" /> <p:message id="argValueMessage" for="argValue" /> </cc:implementation> 

Important. The mycomponent component is also used inside editItemDlg (in the same way as in "anotherDlg"), that is, inside the dialog and forEach-loop)

If I click the editButton button, I get:

 java.lang.IllegalArgumentException: Component ID anotherForm:j_idt192:argValue has already been found in the view. 

Its rather strange, because "anotherDlg" in this case is not open, but, apparently, has already been visualized.

I get the following information in StackTrace (only the relevant parts are shown):

  +id: j_idt192 type: javax.faces.component.UINamingContainer@399bd0dc +id: j_id2 type: javax.faces.component.UIPanel@24ad3910 +id: argValue <=============== type: org.primefaces.component.inputtext.InputText@687d5c3f +id: argValueMessage type: org.primefaces.component.message.Message@7e3361b0 +id: argValue <=============== type: org.primefaces.component.inputtext.InputText@5f52aa8a +id: argValueMessage type: org.primefaces.component.message.Message@2c3a7aea 

So, somehow, these components are obtained twice, but I cannot understand why.

I went through the SO answer , but I can not determine which of the listed reasons is the problem in my case. I do not use bindings.

What I tried so far: played with setting the identifier without explanation, i.e. surrounded mycomonent, passing loop counters as component identifier, etc. without success. I think the problem cannot be resolved in mycomponent. The only workaround I found was to create a physical copy of mycomponent and link to that copy in my other form (so editItemDlg and anotherDlg do not use the same components).

Any help is appreciated

+5
source share
2 answers

You do not have to assign an identifier for entering text on your component.

If you iterate over an array in your form, it is sure that your text input element will be created more than once.

The specified identifier must be unique among all components (including faces) that are descendants of the closest ancestor of the UIComponent, which is NamingContainer, or within the area of โ€‹โ€‹the entire component tree, if such an ancestor, which is NamingContainer, does not exist.

As indicated by the UINamingContainer .

Let's consider that your controller.allArgs has two items in a list.

Generated Output:

 <form id="anotherForm"> <input type="text" id="**argValue**"> <p:message> <input type="text" id="**argValue**"> <p:message> </form> 

And this will result in a duplicate id exception.

You can create a new naming container so that your input id unique or adds information about the index of your addition.

0
source

You now have several JSF components with the same identifier that will not work.

When creating components dynamically, you need to add some iteration index to the corresponding identifiers.

 <p:inputText id="argValue_#{bean.counter}" value="#{cc.attrs.arg}" /> <p:message id="argValueMessage_#{bean.counter}" for="argValue" /> 

The best you can do is completely remove the id tag and let JSF automatically generate them.

Unless, of course, you confirm these identifiers from another place.

0
source

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


All Articles