Updating a dynamic component inside a p:tab "locks up" UI

UI Components for JSF
Post Reply
User avatar
Lawyno
Posts: 9
Joined: 19 May 2011, 11:33

14 Nov 2011, 17:18

Hi there,

I'll make it short.

[EDIT]
Gosh! Forgot the environment! Shame on me! :D
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;
	}
}
Create a page (facelet) like that:

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>
Result:
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:
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"
("myTemplate" is the ID of an included .xhtml file)
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? :shock:

[EDIT]
Created an issue: http://code.google.com/p/primefaces/iss ... il?id=2800
[/EDIT]

Kind regards,

Benny
Primefaces 3.0.RC2/3.0-SNAPSHOT - Mojarra 2.1.3 - JBoss AS 7.0.2.Final/Glassfish 3.1.1

xbellox
Posts: 20
Joined: 13 Jan 2012, 20:12

05 Jun 2012, 14:05

This bug was marked as 'WontFix', but it would be really nice if the patch (in comments) was applied.

I'm behind a proxy, so I'm not able to chekout full source-code, apply the patch and recompile it for every version released.

It's a quite simple patch, with a tiny change, so don't fully understand why the patch is not applied to primefaces.

Please reconsider the issue status :)
PrimeFaces 3.3.1 | Tomcat 7.0.29 | MyFaces 2.1.8 (JSF 2.1)
Eclipse Indigo SR2 | JDK1.7 | Java EE 6 | Oracle 10.2
Windows 7 | Google Chrome
--
Eduardo Bello

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 22 guests