Note that there are some explanatory texts on larger screens.

plurals
  1. PODuplicate id when dynamically adding new component to JSF component tree
    primarykey
    data
    text
    <p>Using JSF 2.1, Mojarra 2.1.3, Glassfish 3.1.1, and PrimeFaces 3.3.1</p> <p>I'm trying to handle processing field level security in JSF, on the preRenderView event, and having issues when needing to add a dynamic component to the JSF component tree. On first render, everything is fine and field level security is processed. After any sort of update, however, Mojarra complains about a duplicate id even though, through printing to the console, my add code is only running once per update.</p> <p>It appears as if Mojarra isn't clearing the component tree for postbacks and thus each subsequent rendered update adds an additional version of the component to the tree.</p> <p>Thanks for any help anyone can provide. Here's some dumbed-down sample code. On commandButton click the error is thrown.</p> <p>index.xhtml:</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" &gt; &lt;f:event listener="#{lifeCycle.event}" type="preRenderView" /&gt; &lt;h:body&gt; &lt;h:form id="form" prependId="false"&gt; &lt;h:panelGroup id="testPanel"&gt; &lt;h:inputText id="viewSec" value="viewSec node"/&gt;&lt;br/&gt; &lt;/h:panelGroup&gt; &lt;p:commandButton update="testPanel"/&gt; &lt;/h:form&gt; &lt;/h:body&gt; &lt;/html&gt; </code></pre> <p>LifeCycle.java:</p> <pre><code>package com.dynamic.test; import java.io.Serializable; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.component.UIComponent; import javax.faces.component.UIViewRoot; import javax.faces.component.html.HtmlOutputText; import javax.faces.component.visit.VisitContext; import javax.faces.context.FacesContext; import javax.faces.event.ComponentSystemEvent; @ManagedBean @RequestScoped public class LifeCycle implements Serializable { public void event(ComponentSystemEvent event){ FacesContext facesContext = FacesContext.getCurrentInstance(); UIViewRoot root = facesContext.getViewRoot(); NodeInspector visitCallback = new NodeInspector(); root.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), visitCallback); List&lt;UIComponent&gt; securityEnabledComponents = visitCallback.getSecurityEnabledComponents(); for (UIComponent securityEnabledComponent : securityEnabledComponents) { if(securityEnabledComponent.getClientId().equals("viewSec")){ List&lt;UIComponent&gt; childList = securityEnabledComponent.getParent().getChildren(); int targetPosition = securityEnabledComponent.getParent().getChildren().indexOf(securityEnabledComponent); HtmlOutputText outputTextComponent = new HtmlOutputText(); outputTextComponent.setId(securityEnabledComponent.getId()); outputTextComponent.setValue(securityEnabledComponent.getAttributes().get("value")); childList.set(targetPosition, outputTextComponent); } } } } </code></pre> <p>NodeInspector.java</p> <pre><code>package com.dynamic.test; import java.util.ArrayList; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.component.visit.VisitCallback; import javax.faces.component.visit.VisitContext; import javax.faces.component.visit.VisitResult; import javax.faces.context.FacesContext; public class NodeInspector implements VisitCallback { private List&lt;UIComponent&gt; securityEnabledComponents = new ArrayList&lt;UIComponent&gt;(); FacesContext facesContext = FacesContext.getCurrentInstance(); @Override public VisitResult visit(final VisitContext context, final UIComponent target) { if(target.getClientId().equals("viewSec")){ securityEnabledComponents.add(target); } return VisitResult.ACCEPT; } public List&lt;UIComponent&gt; getSecurityEnabledComponents() { return securityEnabledComponents; } } </code></pre> <p>Error:</p> <pre><code>SEVERE: JSF1007: Duplicate component ID viewSec found in view. ... +id: j_idt2 type: &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; +id: j_idt3 type: javax.faces.component.UIOutput@17098e7 +id: form type: javax.faces.component.html.HtmlForm@14677de +id: testPanel type: javax.faces.component.html.HtmlPanelGroup@167ab25 +id: viewSec &lt;=============== type: javax.faces.component.html.HtmlOutputText@14a3d2e +id: viewSec &lt;=============== type: javax.faces.component.html.HtmlOutputText@f6a607 +id: j_idt4 type: &lt;br/&gt; +id: j_idt5 type: org.primefaces.component.commandbutton.CommandButton@1380fc5 +id: j_idt6 type: &lt;/html&gt;... SEVERE: Error Rendering View[/index.xhtml] java.lang.IllegalStateException: Component ID viewSec has already been found in the view. at com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)... </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload