I'm having problems rerendering the relevant parts of my view without having to resort to #form or the like.
I have a composite component like this:
wrapper.xhtml:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">
<cc:interface componentType="compositeComponent">
<cc:attribute required="false" name="foo" />
</cc:interface>
<cc:implementation>
<a4j:region>
<h:panelGroup id="content" layout="block" styleClass="my-wrapper">
<h1>TITLE</h1>
<c:forEach items="#{element.children}" var="element">
<ui:include src="element.xhtml">
<ui:param name="level" value="0" />
</ui:include>
</c:forEach>
</h:panelGroup>
</a4j:region>
</cc:implementation>
</ui:composition>
and element.xhtml:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">
<h:outputLabel styleClass="level-#{level}">
#{element.label}
<a4j:ajax event="click"
listener="#{controller.updateElements(element)}"
execute="#this" render="#region" />
</h:outputLabel>
<c:if test="#{element.someTest}">
<c:forEach items="#{element.children}" var="element">
<ui:include src="element.xhtml">
<ui:param name="level" value="#{level + 1}" />
</ui:include>
</c:forEach>
</c:if>
</ui:composition>
Now the problem is, although I'm setting an <a4j:region> around the wrapper, and setting the render expression in the children to #region, it still only renders the single clicked upon child on rerender.
I searched the web and SO but couldn't find a reason for this, does the include implicitly create a namespace or naming container (which would be treated as a region?)? Couldn't find anything like this, but if so, how would I avoid this? I want the entire wrapper (and only that, not #form or #all or the like) to be rerendered upon clicking on a child.
What am I missing?
#region is only used for execution. The <a4j:region> doesn't generate any HTML so you cannot use it for rendering.
Related
I am a beginner programming Java and I am doing a project using primefaces. I want to include another XHTML page in an XHTML page. The include page is in /WEB-INF/facelets/include.xhtml (It has some data from a Managed Bean)
In my "page.xhtml", at first, I put this line inside <ui:define name="content">:
<ui:include src="WEB-INF/facelets/include.xhtml" />
But, it does not work.
Later, I tried to do this inside <ui:define name="content">
<ui:include src="WEB-INF/facelets/include.xhtml">
<ui:param name="fullName" value="#{identityInformationBean.fullName}" />
</ui:include>
And in the "include.xhtml":
<h:outputText
rendered="#{fullName!=null}"
value="#{fullName}" />
But, it does not work too. Nevertheless, if I do this:
On "page.xhtml"
<ui:include src="WEB-INF/facelets/include.xhtml">
<ui:param name="fullName" value="Helen" />
</ui:include>
The "include.xhtml" receives the information correctly.
I'd tried to registering the include file as a tagfile, as suggest here How to include another XHTML in XHTML using JSF 2.0 Facelets?
But, it does not work.
Any idea to solve this problem? Thanks!
This is a piece of code from "include.xhtml":
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:outputText
rendered="#{identityInformationBean.fullName!=null}"
value="#{identityInformationBean.fullName}" />
</ui:composition>
This is a piece of code from "page.xhtml":
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" template="templates/generaltemplate.xhtml">
<ui:define name="content">
<h2>
<h:outputText value="Identity Information"/>
</h2>
</ui:define>
</ui:composition>
I'm not sure why you need ui:param. Think of the include file as just saving you the trouble of typing that included code into all the pages that might use it. You don't need to pass it a parameter.
What about using a single line of code: <ui:include src="WEB-INF/facelets/include.xhtml"/> And the include file would have <h:outputText value="#{identityInformationBean.fullName}"/>
This question already has answers here:
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?
(2 answers)
Closed 6 years ago.
As per HTML standard nested form not allowed and JSF follow same thing but if we have design like below
MainPage.xhtml
<ui:composition template="../templates/home.xhtml">
<ui:define name="content">
<h:form>
<rich:panel>
..........................................
..........................................
</rich:panel>
<rich:panel>
<ui:insert name="createLinkTemplate">
<ui:include src="../pages/page.xhtml" />
</ui:insert>
</rich:panel>
<h:form>
</ui:define>
</ui:composition>
Content inside page.xhtml
<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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:head>
</h:head>
<h:body>
<h:form id="formID">
<rich:panel>
..........................
............................
............................
</rich:panel>
</h:form>
</h:body>
</html>
is this come under the nested case ?
home-template.xhtml content
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:c="http://java.sun.com/jsp/jstl/core">
...................................................
...................................................
...................................................
<rich:panel styleClass="tabs-main" id="tabsMain">
<h:form id="contentform">
<ui:insert name="content"/>
</h:form>
</rich:panel>
</h:body>
</html>
Along with that one more question First i am alnding to Main.xhtml page from here i am going to page.xhtml and when from there i am coming back all the value which i write in textbox or select from drop down gone and i got a empty form .
Forms are nested when they are nested in the resulting page - the shape of templates and includes has nothing to do with this.
Browser has no way of knowing where <form> tags come from. All it sees is that there are two form tags, one placed in the other.
I have a Facelet that might be used in different applications.
I don't to copy it, but reuse it. I need to pass the backing bean that will manage the view as a parameter, as some logic may vary according to the application where it is used in.
I don't want to use a composite component, but just include the Facelet and specify which bean will manage the view. How can I achieve this?
Let me give an example:
<ui:composition template="/resources/common/templates/template.xhtml"
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:c="http://java.sun.com/jsp/jstl/core" xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich" xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<ui:define name="content">
<!-- somehow establish the backing bean that will manage formView.xhtml -->
<!-- f:set assign="ParameterBean" value="#{Bean}" / -->
<ui:include src="formView.xhtml" />
</ui:define>
</ui:composition>
formView.xhtml :
<ui:composition template="/resources/common/templates/template.xhtml"
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:c="http://java.sun.com/jsp/jstl/core" xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich" xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<ui:define name="content">
<h:outputText value="#{ParameterBean.texto}" />
</ui:define>
</ui:composition>
You can use <ui:param> for that. It needs to be nested in the <ui:include>.
<ui:include src="formView.xhtml">
<ui:param name="ParameterBean" value="#{Bean}" />
</ui:include>
Unrelated to the concrete problem, standard Java Naming Conventions state that instance variable names must start with lower case. You should change your code in such way that respectively parameterBean and #{bean} will be used.
Because I would have found it helpful yesterday, when I was looking for this, here is a simple version of how to do this, without the extraneous template, defines and namespaces:
File1.xhtml (the root tag doesn't matter)
<ui:include src="File2.xhtml">
<ui:param name="person" value="#{whatever_value_you_want_to_pass}" />
</ui:include>
File2.xhtml
<ui:composition ... xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" ... >
<h:outputLabel value="#{person.name}" />
</ui:composition>
You can also nest further in the same manner.
File1.xhtml
<ui:include src="File2.xhtml">
<ui:param name="person" value="#{whatever_value_you_want_to_pass}" />
</ui:include>
File2.xhtml
<ui:composition ... xmlns:ui="http://java.sun.com/jsf/facelets" ... >
<ui:include src="File3.xhtml">
<ui:param name="name" value="#{person.name}" />
</ui:include>
</ui:composition>
File3.xhtml
<ui:composition ... xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" ... >
<h:outputLabel value="#{name.length}" />
</ui:composition>
Hi I have a template with header, menu and content, and I built my dynamic menu menubar, now I want to know how I can do to make the click of each option on my menu only update the contents of my layout and header and menu will remain as they are ... here is my template:
<div id="header" style="height: 70px;">
<ui:insert name="header" >
<ui:include src="header.xhtml" />
</ui:insert>
</div>
<div id="menu" style="height: 50px;">
<ui:insert name="menu" >
<ui:include src="menu.xhtml" />
</ui:insert>
</div>
<div id="content">
<ui:insert name="content" >
<ui:include src="content.xhtml" />
</ui:insert>
</div>
can someone help? Thank you!
I suggest you to use JSF Templating. By applying this approach, your pages are easy to extend and reuse.
This is my example which use p:layout, ui:composition and etc.
layout.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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Layout-menu</title>
</h:head>
<h:body>
<p:layout>
<p:layoutUnit position="west"
resizable="true"
size="250"
minSize="40"
maxSize="400">
<h:form>
<p:menu>
<p:submenu label="Navigations">
<p:menuitem value="input"
outcome="inputText"
icon="ui-icon-star"/>
<p:menuitem value="dropdown"
outcome="selectOneMenu"
icon="ui-icon-star"/>
</p:submenu>
</p:menu>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center">
<ui:insert name="source" />
</p:layoutUnit>
</p:layout>
</h:body>
</html>
inputText.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
template="layout.xhtml">
<ui:define name="source">
<h:form>
inputText
</h:form>
</ui:define>
</ui:composition>
selectOneMenu.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
template="layout.xhtml">
<ui:define name="source">
<h:form>
selectOneMenu
</h:form>
</ui:define>
</ui:composition>
You can run test at the layout.xhtml page like this http://host:port/project/layout.xhtml
You can see more information about Templating from another site such as JSF 2 Templating With Facelets Example, Using Facelets Templates and etc.
You should use JSF Templating that show in #wittakarn example combination with DefaultMenuItem and setUrl to other page, and the other page use the same template, the header and menu will remain.
So I have:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:body>
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:outputText value="Test!!!" />
</ui:define>
</ui:composition>
</h:body>
</html>
as my main page on my website and on template.xhtml:
<div id="content">
<h:panelGroup layout="block" styleClass="centercss">
<ui:insert name="content" />
</h:panelGroup>
</div>
...in the middle of the footer and the header views.
Now if I try to change the template="template.xhtml" to template.jsf it does not appear anywhere... the way it is right now I get my 'content' page perfectly in the middle of header and footer on the eclipse preview, but on the browser there's no content at all.
Im using primefaces3.1.1 and I have javax.faces-2.1.14 + jsf-api and jsf-impl, so I think its primefaces 3 and JSF 2.
What is the problem here ?
I think you are using facelets (templating) in a wrong way. You should'nt have html and body tags on your main page. The page that will use the template must be defined in a <ui:composition> tag, and the template shall define the page as a whole (html, body, head tags, etc).
Example:
index.html
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"
template="template.xhtml">
<ui:define name="content">
<h:outputText value="Test!!!" />
</ui:define>
</ui:composition>
template.xhtml
<!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:ui="http://java.sun.com/jsf/facelets">
<h:body>
<div id="content">
<h:panelGroup layout="block" style="background-color: red;">
<ui:insert name="content" />
</h:panelGroup>
</div>
</h:body>
</html>