I'll make it short.
[EDIT]
Gosh! Forgot the environment! Shame on me!
All this happens on Primefaces 3.0.M4/3.0.RC1-SNAPSHOT (maybe all 3.0.x) with Mojarra 2.1.3 on JBoss AS 7.0.2.Final/Glassfish 3.1.1
[/EDIT]
Create a backing bean like this:
Code: Select all
@ManagedBean
@ViewScoped
public class DynamicComponentBean implements Serializable
{
private static final long serialVersionUID = 1L;
private static final Logger log = Logger.getLogger(DynamicComponentBean.class.getCanonicalName());
private static final Random random = new Random();
private transient UIComponent component1, component2;
private int updateCount1 = 0;
private int updateCount2 = 0;
public UIComponent getComponent1()
{
return component1;
}
public void setComponent1(UIComponent component)
{
this.component1 = component;
}
public UIComponent getComponent2()
{
return component2;
}
public void setComponent2(UIComponent component)
{
this.component2 = component;
}
public void update1()
{
log.info("update1()...");
if (component1 == null)
{
log.warning("component1 not yet initialized!");
return;
}
component1.getChildren().clear();
updateCount1++;
log.log(Level.INFO, "updateCount1: {0}", updateCount1);
final FacesContext fc = FacesContext.getCurrentInstance();
final Application app = fc.getApplication();
HtmlOutputText text = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
text.setValue("UpdateCount: " + updateCount1);
OutputPanel panel = (OutputPanel) app.createComponent(OutputPanel.COMPONENT_TYPE);
panel.setLayout("block");
panel.setStyle(getRandomStyle());
panel.getChildren().add(text);
component1.getChildren().add(panel);
}
public void update2()
{
log.info("update2()...");
if (component2 == null)
{
log.warning("component2 not yet initialized!");
return;
}
component2.getChildren().clear();
updateCount2++;
log.log(Level.INFO, "updateCount2: {0}", updateCount2);
final FacesContext fc = FacesContext.getCurrentInstance();
final Application app = fc.getApplication();
HtmlOutputText text = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
text.setValue("UpdateCount: " + updateCount2);
OutputPanel panel = (OutputPanel) app.createComponent(OutputPanel.COMPONENT_TYPE);
panel.setLayout("block");
panel.setStyle(getRandomStyle());
panel.getChildren().add(text);
component2.getChildren().add(panel);
}
private static final String[] STYLES = {
"border: dotted 1px orange;",
"border: dotted 1px green;",
"border: dotted 1px blue;",
"border: dotted 1px red;",
"border: dashed 1px orange;",
"border: dashed 1px green;",
"border: dashed 1px blue;",
"border: dashed 1px red;"
};
private String getRandomStyle()
{
String style = "padding: .5em;";
style += STYLES[random.nextInt(STYLES.length)];
return style;
}
}
Code: Select all
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Dynamic Component Update Bug</title>
</h:head>
<h:body>
<p:panel header="Working">
<h:form>
<h:panelGrid columns="2">
<p:commandButton actionListener="#{dynamicComponentBean.update1}" update="dyncomp1" value="update" />
<p:outputPanel id="dyncomp1" binding="#{dynamicComponentBean.component1}" />
</h:panelGrid>
</h:form>
</p:panel>
<p:spacer />
<p:tabView id="myTabView" widgetVar="myTabView">
<p:tab id="myTabViewTab" title="Not working">
<h:form id="myTabViewForm">
<h:panelGrid id="myTabViewGrid" columns="2">
<p:commandButton actionListener="#{dynamicComponentBean.update2}" update="dyncomp2" value="update" />
<p:outputPanel id="dyncomp2" binding="#{dynamicComponentBean.component2}" />
</h:panelGrid>
</h:form>
</p:tab>
</p:tabView>
</h:body>
</html>
The bound component inside the panel updates correctly.
You can press the "update" button a hundred times.
It just works.
Well... that is... until you press the "update" button inside the "p:tab" 2-3 times.
Then even the component inside the panel won't work anymore
There must be something wrong with the "p:tab" (or "p:tabView and "p:accordionPanel") component which "locks up" the whole AJAX/UI stuff.
In my "real" application I also get an exception like this:
("myTemplate" is the ID of an included .xhtml file)WARN - No handlers found for exception javax.faces.FacesException: java.lang.NumberFormatException: Trying to extract rowIndex from clientId 'myTabView:myTabViewForm:j_id5' For input string: "myTemplate"
I'm also curious about that clientId.
I mean: all auto-generated IDs are named like "j_jdt[n]", aren't they?
Perhaps it's just that very little missing "t", which does all the trouble?
[EDIT]
Created an issue: http://code.google.com/p/primefaces/iss ... il?id=2800
[/EDIT]
Kind regards,
Benny