Using <ui:include> in center facet of <af:decorativeBox> - jsf

I moved from JSF 1.2 using JSP to JSF 2.1 using Facelets.
I use oracle ADF Faces as component library.
The layout of my main page doesn't work anymore with Facelets.
Here is my layout :
<af:form id="mainForm">
<af:decorativeBox theme="medium" styleClass="AFVisualRoot">
<f:facet name="center">
<!-- Main page -->
<af:panelStretchLayout topHeight="35" bottomHeight="20" >
<!-- Top menu -->
<f:facet name="top">
<af:panelStretchLayout endWidth="255" startWidth="100%">
<f:facet name="end">
</f:facet>
<f:facet name="start">
</f:facet>
</af:panelStretchLayout>
</f:facet>
<!-- Page footer -->
<f:facet name="bottom">
<af:region id="footerRegion" showHeader="never"
value="#{main.footerModel}" />
</f:facet>
<!-- Page body -->
<f:facet name="center">
<af:panelSplitter orientation="horizontal"
splitterPosition="450">
<f:facet name="first">
<af:region id="browserRegion" showHeader="never"
value="#{main.browserModel}" />
</f:facet>
<f:facet name="second">
<af:region id="contentRegion" showHeader="never"
value="#{main.contentModel}" />
</f:facet>
</af:panelSplitter>
</f:facet>
</af:panelStretchLayout>
</f:facet>
</af:decorativeBox>
</af:form>
As it says in the documentation for the center facet of the decorativeBox "multiple facet components in facelets are not supported by this facet"
How to do the layout of the page and still benefit from the decorativeBox if I still want to use Facelets ?
UPDATE:
my problems comes from using <ui:include> inside facets :
<!-- Top menu -->
<f:facet name="top">
<af:panelStretchLayout endWidth="255" startWidth="100%">
<f:facet name="end">
</f:facet>
<f:facet name="start">
<ui:include src="/components/menu.xhtml" />
</f:facet>
</af:panelStretchLayout>
</f:facet>
Here is part of menu.xhtml:
<?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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:trh="http://myfaces.apache.org/trinidad/html"
xmlns:tr="http://myfaces.apache.org/trinidad"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
xmlns:afh="http://myfaces.apache.org/trinidad/html">
<af:menuBar id="headerMenuBar">
<!-- Menu Item -->
</af:menuBar>
</ui:composition>
What is the right way to include a page using Facelet inside ADF components ?

I've tested your layout with both facelets and jspx and I get the same result : both are working.
Your problem is elsewhere.
UPDATE after the question was updated:
<ui:include> tag should be avoided in ADF, please see Programming Best Practices - ADF Faces & JavaScript

Related

Primefaces blockUI and composition

I'm using JSF 2.2, PF 5.3 and GlassFish 4.1.1.
I'm trying to centralize the blockUI content in my web application.
here the code of the my custom blockUI
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<cc:interface>
<cc:attribute name="block" type="java.lang.String"/>
<cc:attribute name="trigger" type="java.lang.String"/>
</cc:interface>
<cc:implementation>
<p:blockUI block="#{cc.attrs.block}" trigger="#{cc.attrs.trigger}">
LOADING<br />
<p:graphicImage library="images" name="ajax-loader.gif"/>
</p:blockUI>
</cc:implementation>
and here the code in which I'm trying to apply this one
<h:form>
...
...
<p:dataTable id="myTable">
<p:column headerText="actions">
<p:commandButton class="triggerableFromBlockUI" action="#{action1}"/>
<p:commandButton class="triggerableFromBlockUI" action="#{action2}"/>
</p:column>
</p:dataTable>
...
...
<myTag:blockUI block="myTable" trigger="#(.triggerableFromBlockUI)"/>
</h:form>
but I see the following error
Cannot find component for expression "myTable".
If I use directly the p:blockUI all is working. Can you help me?
Here the solution found in the Prime Faces Forum
<myTag:blockUI block="#form:myTable" trigger="#(.triggerableFromBlockUI)"/>

PrimeFaces component with outcome attribute renders incorrectly

The problem:
I have a MenuItem component that looks like this - <p:menuitem value="Documents" outcome="/portal/admin/documents.xhtml" /> - but it renders into markup that looks like this - <a href="documents.xhtml">
Details:
There are two XHTML pages at play here. The first is index.xhtml at /portal/index.xhtml and the second is admin-widget.xhtml at /portal/home/admin-widget.xhtml.
Relevant part of index.xhtml:
<ui:fragment rendered="...">
<div class="...">
<p:panel styleClass="...">
<f:facet name="header">
<h:outputText value="Administration" />
</f:facet>
<ui:include src="/portal/home/admin-widget.xhtml" />
</p:panel>
</div>
</ui:fragment>
Relevant part of admin-widget.xhtml:
<h:form style="...">
<ui:fragment rendered="...">
<p:menu style="...">
<p:submenu label="Administration Links">
<p:menuitem value="Documents" outcome="/portal/admin/documents.xhtml" />
</p:submenu>
</p:menu>
<h:link value="Documents" outcome="/portal/admin/documents.xhtml" />
</ui:fragment>
</h:form>
The <h:link> below the <p:menu> was just a test, in order to see if the problem was just with the <p:menuitem> or not. However, the <h:link> also renders incorrectly.
The most interesting thing is that when I view the index.xhtml page, the link is incorrect, but if I view the admin-widget.xhtml page directly, the link is correct. So it has to be something with how I am inserting the page, but I'm not sure what I am doing wrong.
I am using PrimeFaces 5.3 and JSF 2.0.

omnifaces highlight component is not working with richfaces 4 bean validation

I have the maven dependency for omnifaces for version 1.11 (as my target is JDK 1.6). Richfaces 4.5.6 final, myfaces 2.2.8. And, against a viewscoped bean I have got this xhtml:
<ui:define name="content">
<f:loadBundle basename="au.com.erb.facility.ui.facility"
var="property" />
<o:highlight styleClass="error" />
<h:panelGrid columns="2">
<rich:validator event="change">
<o:outputLabel value="#{property.absClientNumber}" for="input1" />
<h:inputText id="input1"
value="#{facilityBean.facilityForEdit.alternateKey.absClientNumber}"
label="ABS Client Number" />
<o:outputLabel value="#{property.facilityid}" />
<h:inputText
value="#{facilityBean.facilityForEdit.alternateKey.facilityId}"
label="Facility Id" />
<h:outputLabel value="#{property.rfsAccountGroup}" />
<h:inputText value="#{facilityBean.facilityForEdit.rfsAccountGroup}"
label="RFS Account Group" />
<h:outputLabel value="#{property.rfsAcctCustomerNumber}" />
<h:inputText
value="#{facilityBean.facilityForEdit.rfsAcctCustomerNumber}"
label="RFS Account Customer Number" />
<h:outputLabel value="#{property.rfsAcctLedger}" />
<h:inputText value="#{facilityBean.facilityForEdit.rfsAcctLedger}"
label="RFS Account Ledger" />
</rich:validator>
</h:panelGrid>
</ui:define>
<!-- Buttons that performs actions on a selected record -->
<!-- or navigate to a relevant screen -->
<ui:define name="buttons">
<h:commandButton id="submitButton" value="#{property.submitLabel}"
action="#{facilityBean.save}" styleClass="wideButton"
onclick="#{rich:component('progressWaitModalPanel')}.show()" />
<h:commandButton id="closeButton" value="#{property.closeLabel}"
action="#{facilityBean.close}" styleClass="wideButton"
immediate="true" />
<rich:popupPanel id="progressWaitModalPanel" modal="true">
<f:facet name="header">
<h:outputText value="Processing your request ...." />
</f:facet>
<h:panelGrid columns="1"
style="width: 100%; border-width: 0px; text-align: center;">
<h:outputText value="Please wait..." styleClass="dataValueStyle" />
</h:panelGrid>
</rich:popupPanel>
</ui:define>
The result is nothing. No higlight. No clue what's going on. Have I missed any installation step? I have the css and xmlnamespace in place. Anything else?
I tried to add required="true" as it was shown in the example, but that did not work either. Not sure whether it is due to richfaces bean validation issue.
The <o:highlight> works server side, based on a.o. UIInput#isValid() in JSF component tree. The <rich:validator> works client side and doesn't manipulate JSF component tree.
This indeed doesn't go well together.
I briefly looked into the HTML/JS code of the <rich:validator> showcase and it appears that they don't add a marker style class to the input elements when it's invalid (e.g. PrimeFaces does), so it's going to be hard to write a workaround when continuing the <rich:validator> approach.
You've basically following options:
Maunally write an oncomplete script which finds the validation error messages and then finds the associated inputs and then set the desired marker style class on it.
Report an issue to RichFaces guys and ask them to add a marker style class to invalid inputs via <rich:validator>, so you could style them individually.
Drop <rich:validator> and replace it by server side validation via <f:ajax>.

How do I conditionally render an <f:facet>?

I would like to be able to conditionally omit a footer from a PrimeFaces panel element:
<p:panel header="some text">
<f:facet name="footer">
#{message}
</f:facet>
<!-- ... -->
</p:panel>
I hoped that the rendered attribute would work:
<p:panel header="some text">
<f:facet name="footer" rendered="#{!empty message}">
#{message}
</f:facet>
<!-- ... -->
</p:panel>
But the footer is still rendered, with empty content. It appears that facet does not have the rendered attribute: http://www.jsftoolbox.com/documentation/help/12-TagReference/core/f_facet.html.
What's the right way to do this?
I was able to solve this by swapping the facet out for an attribute. To summarize:
This works
<p:panel ...>
<f:attribute name="footer" value="#{message}"/>
<!-- ... -->
</p:panel>
But this doesn't work
<p:panel footer="#{message}">
<!-- ... -->
</p:panel>
Neither does this
<p:panel ...>
<f:facet name="footer">#{message}</f:facet>
<!-- ... -->
</p:panel>
Nor this
<p:panel ...>
<f:facet name="footer">
<h:outputText value="#{message}" rendered="#{!empty message}"/>
</f:facet>
<!-- ... -->
</p:panel>
by "works" I mean:
"renders no footer — not just an empty footer — when #{message} is empty or null; otherwise, correctly renders the footer with the specified text."
PrimeFaces forum thread on this issue
You could declare a ui:param and let the template check the param while renderring.
The facet in the template could then be declared as:
<f:facet name="#{hideFooter == null or not hideFooter ? 'footer' : ''}">
#{message}
</f:facet>
Any page can then declare this param
<ui:param name='hideFooter' value='#{some rule}' />
and set the appropriate rule for the param. For any page that does not declare the param, the footer will be displayed.
Here's what I did in trying to conditionally render a facet within a composite component.
<composite:interface>
<composite:facet name="header" required="false" />
</composite:interface>
<composite:implementation>
<p:panel>
<c:if test="#{empty component.facets.header}" >
<f:facet id="#{cc.attrs.id}_default_header" name="header">
all sorts of stuff here
</f:facet>
</c:if>
<c:if test="#{not empty component.facets.header}">
<composite:insertFacet id="#{cc.attrs.id}_custom_header" name="header" />
</c:if>
<composite:insertChildren id="#{cc.attrs.id}_content"/>
</p:panel>
</composite:implementation>
This let's the user of the composite component supply the header facet if they want, and if they don't, we supply a default. Obviously, instead of providing a default, you could simply not do anything.
This mixes c:if in jsf controls, but we didn't see any adverse effects.
I have come across a similar issue with plain JSF. I am not sure how a <p:panel> is rendered, but if it is rendered as a table, you can try this:
First, declare a CSS-class like this:
.HideFooter tfoot {
display: none;
}
Then set that class conditionally on the panel:
<p:panel styleClass="#{renderFooterCondition ? null : 'HideFooter'}">
The footer is still rendered in the JSF-sense, but it is not displayed and does not take up any space in the page when viewed by the user-agent.
I successfully solved this problem using ui:fragment
<ui:fragment rendered="...Test...">
<f:facet name="footer">
...
</f:facet>
</ui:fragment>
works for example to conditionnaly render the footer of a primefaces datatable (the rendered attribute of the facet does not work).
Not sure how well this would work for your footer, but I had the same issue with a legend I was trying to conditionally render. I fixed it by using the rendered on anything inside the facet tag.
<p:fieldset>
<f:facet name="legend">
<h:outputText value="#{header1}" rendered="#{header1.exists}"/>
<h:outputText value="#{header2}" rendered="#{not header1.exists}"/>
</f:facet>
content
</p:fieldset>
I had difficulty trying c:if with my ui:repeat, so this was my solution. Not quite the same as your problem, but similar.
Facets are not intended to render HTML, which is why it doesn't have the rendered attribute. Facets add functionality to a page. The term facet is probably a poor choice of name. It's very ambiguous.
..if the list compiled by ITworld's Phil Johnson has it right, the
single hardest thing developers do is name things.
ie.
JSF facets
A project facet is a specific unit of functionality that you can add to a project when that functionality is required. When a project facet is added to a project, it can add natures, builders, classpath entries, and resources to a project, depending on the characteristics of the particular project. JSF facets define the characteristics of your JSF enabled web application. The JSF facets specify the requirements and constraints that apply to your JSF project.
The JSF facets supply a set behaviors and capabilities to your web application.
This is a counter-answer to the answer from Ludovic Pénet.
This worked for me in <f:facet name="footer"> in selected p:column items of a p:dataTable (Primefaces 5.3):
...
Note how I have the ui:fragment inside the f:facet, not outside (not wrapping) it. It definitely completely removes the entire row when every footer facet is tested to NOT render (as far as I can tell, independent of the content within the ui:fragment).
Try with this, from primefaces web page
<p:columnGroup type="footer">
<p:row>
<p:column colspan="3" style="text-align:right" footerText="Totals:" />
<p:column footerText="your value in ajax" />
<p:column footerText="your value in ajax" />
</p:row>
</p:columnGroup>
clik here, to view primefaces' webpage
For those who landed here trying to hide the footer, instead of header, but the syntax component.facets.footer didn't work, should try this:
<p:panel id="panelContent">
<c:if test="#{not empty cc.facets.footer}">
<f:facet name="footer" height="100%">
your content
</f:facet>
</c:if>
</panel>
Why don't you enclose the content of the footer into a panelGroup which has the rendered attribute?
This way:
<p:panel header="some text">
<f:facet name="footer">
<h:panelGroup rendered="#{!empty message}">
#{message}
</h:panelGroup>
</f:facet>
<!-- ... -->
</p:panel>
I do it in my weapp and it works, no footer is rendered.
I don't use primefaces though, I do it with h:datatable, but I think that it must works with p:panel too.
I try this solution and ok. (http://www.coderanch.com/t/431222/JSF/java/dynamically-set-panel-header-condition)
<rich:dataGrid value="#{myMB.student.list}" rendered="#{!empty myMB.student and !empty myMB.student.list}" var="st" rowKeyVar="row">
<rich:panel>
<f:facet name="header">
<h:panelGroup id="panelHeader">
<h:outputText value="Just one student" id="header1" required="true" rendered="#{!myMB.manyStudents}"/>
<h:outputText value="#{row+1}º Student" id="header2" required="true" rendered="#{myMB.manyStudents}"/>
</h:panelGroup>
</f:facet>
<rich:panel>

This page calls for XML namespace declared with prefix br but no taglibrary exists

I just finished the Netbeans introduction to Hibernate tutorial ( http://netbeans.org/kb/docs/web/hibernate-webapp.html#01 ) and I am getting the following error:
"This page calls for XML namespace declared with prefix br but no taglibrary exists"
Now, I have seen a similar question somewhere else:
http://forums.sun.com/thread.jspa?threadID=5430327
but the answer is not listed there. Or, if it is, then I am clearly missing it -- line one of my index.xhtml file reads "http://www.w3.org/1999/xhtml". It also does not explain why, when I reload localhost:8080, the message disappears.
Here is my index.xhtml file:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="./template.xhtml">
<ui:define name="body">
<h:form>
<h:commandLink action="#{filmController.previous}" value="Previous #{filmController.pageSize}" rendered="#{filmController.hasPreviousPage}"/>
<h:commandLink action="#{filmController.next}" value="Next #{filmController.pageSize}" rendered="#{filmController.hasNextPage}"/>
<h:dataTable value="#{filmController.filmTitles}" var="item" border="0" cellpadding="2" cellspacing="0" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="Title"/>
</f:facet>
<h:outputText value="#{item.title}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Description"/>
</f:facet>
<h:outputText value="#{item.description}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{filmController.prepareView}" value="View"/>
</h:column>
</h:dataTable>
<br/>
</h:form>
</ui:define>
</ui:composition>
</html>
The problem clearly comes from the <br/> tag, and facelets is trying to interpret it as a JSF/facelets tag with a prefix.
If we follow the standards, this tag should look like this <br /> (with a space before the slash). Try it that way, and if it doesn't work, try removing it.
I'm a few years late, but I have just done the same Hibernate tutorial, and faced exactly the same error. However, I do not think that the problem is related to the file index.xhtml. And while another poster is correct that the break tags should have a space, that change does not prevent the error "This page calls for XML namespace declared with prefix br but no taglibrary exists"
The problem lies in another xhtml file in the tutorial named browse.xhtml. You can see the content of that file using the tutorial link in the opening post. It contains an unmatched trailing </html> tag, and no reference to the http://www.w3.org/1999/xhtml namespace.
Pasting the content of that file into a HTML validator (e.g. validator.w3.org ) highlights the problems.
The solution that worked for me was to add the missing opening <html> tag:
<html xmlns="http://www.w3.org/1999/xhtml">
Alternatively, remove that unmatched trailing </html> tag, and add
xmlns="http://www.w3.org/1999/xhtml" to the opening <ui:composition> tag.

Resources