/test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:composite="http://java.sun.com/jsf/composite/components">
<f:view>
<h:head>
<title>Default Title</title>
</h:head>
<h:body>
<h:form id="form">
<composite:test id="composite"/>
</h:form>
</h:body>
</f:view>
</html>
/resources/components/test.xhtml
<?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:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:composite="http://java.sun.com/jsf/composite/components"
xmlns:p="http://primefaces.org/ui">
<head>
<title>(For validation only)</title>
</head>
<body>
<cc:interface>
</cc:interface>
<cc:implementation>
<p:panel header="header foo bar">
<p:panel>
<f:facet name="header">
<h:outputText value="foo"/>
<h:outputText value="bar"/>
</f:facet>
</p:panel>
</p:panel>
</cc:implementation>
</body>
</html>
This combination gives:
GRAVE: Error Rendering View[/test.xhtml]
java.lang.IllegalStateException: Component ID form:composite:j_id2 has already been found in the view.
with this tree:
GRAVE: JSF1007: Duplicate component ID form:composite:j_id2 found in view.
GRAVE: +id: j_id1
type: javax.faces.component.UIViewRoot@47080ae5
+id: javax_faces_location_HEAD
type: com.sun.faces.component.ComponentResourceContainer@2daf59b3
+id: j_id3
type: javax.faces.component.UIOutput@532a0e33
+id: j_id4
type: javax.faces.component.UIOutput@6e0a60ec
+id: j_id5
type: javax.faces.component.UIOutput@6b615e64
+id: j_id6
type: javax.faces.component.UIOutput@457c2e4f
+id: j_id7
type: javax.faces.component.UIOutput@5bc4682c
+id: j_id8
type: javax.faces.component.UIOutput@3b934fc5
+id: j_idt37
type: <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+id: j_idt38
type: <html xmlns="http://www.w3.org/1999/xhtml">
+id: j_idt39
type: javax.faces.component.UIOutput@610364d1
+id: j_idt40
type:
<title>Default Title</title>
+id: j_idt55
type: javax.faces.component.UIOutput@25d00719
+id: form
type: javax.faces.component.html.HtmlForm@7c820db3
+id: composite
type: javax.faces.component.UINamingContainer@3e51a2a1
+id: j_id2
type: javax.faces.component.UIPanel@445a2d11
+id: j_idt52
type: org.primefaces.component.panel.Panel@618c17fd
+id: j_idt53
type: org.primefaces.component.panel.Panel@347b1513
+id: j_id2
type: javax.faces.component.UIPanel@7c44da25
+id: j_idt50
type: javax.faces.component.html.HtmlOutputText@7ca4ad4f
+id: j_idt54
type: javax.faces.component.html.HtmlOutputText@1f6e5d77
+id: j_idt47
type:
</html>
However, if I change composite component this way:
/resources/components/test.xhtml
<?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:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:composite="http://java.sun.com/jsf/composite/components"
xmlns:p="http://primefaces.org/ui">
<head>
<title>(For validation only)</title>
</head>
<body>
<cc:interface>
</cc:interface>
<cc:implementation>
<p:panel header="header foo bar">
<p:panel>
<f:facet name="header">
<h:panelGroup>
<h:outputText value="foo"/>
<h:outputText value="bar"/>
</h:panelGroup>
</f:facet>
</p:panel>
</p:panel>
</cc:implementation>
</body>
</html>
Adding a <h:panelGroup>
in <f:facet>
solves the problem.
Bad tree indexing or am I missing something? I'm using mojarra 2.1.3 and PrimeFaces 3.0.M4-SNAPSHOT under Glassfish 3.1.1.
According to JSF2 documentations, The <f:facet>
tag can have only one child. If you have many elements which you want to nest inside a facet tag, you should first wrap them in some other container like <h:panelGroup>
, then put that single parent container in the <f:facet>
.
exactly what you have done!
JavaServer Faces 2.0, The Complete Reference - Authors: Ed Burns, Chris Schalk
(ISBN-10: 0071625097 | ISBN-13: 978-0071625098)
Page Number: 538
Abstract:
The f:facet tag signifies a nested component that has a special relationship to its enclosing tags. For example, stating that the "header" of a table is to be provided by a JSF component. This element adds the component represented by the JSF action in its body as a facet with the specified name to the component represented by the closest JSF component parent action element. This tag only allows one component to be nested whithin itself. To use multiple component as a facet, create them as children of a simple container component. For example, nest the corresponding HTML library component actions within the body a panelGroup component.