PrimeFaces Layout and h:form - html

The Primefaces Documentation states that the following code will be invalid due to the fact that every layoutUnit needs its own form:
<p:layout fullPage="true">
<h:form>
<p:layoutUnit position="north">
<p:inputText value="#{testBean.input1}" />
</p:layoutUnit>
<p:layoutUnit position="center">
<p:inputText value="#{testBean.input2}" />
<p:commandButton value="save" action="#{testBean.save}" />
</p:layoutUnit>
<p:layoutUnit position="south">
<p:inputText value="#{testBean.input3}" />
</p:layoutUnit>
</h:form>
</p:layout>
However, when I nest p:layout inside of a form, the code works without any problem:
<h:form>
<p:layout fullPage="true">
<p:layoutUnit position="north">
<p:inputText value="#{testBean.input1}" />
</p:layoutUnit>
<p:layoutUnit position="center">
<p:inputText value="#{testBean.input2}" />
<p:commandButton value="save" action="#{testBean.save}" />
</p:layoutUnit>
<p:layoutUnit position="south">
<p:inputText value="#{testBean.input3}" />
</p:layoutUnit>
</p:layout>
</h:form>
What is the explanation for that behaviour? Can my approach of having just a single form tag outside of p:layout cause problems at some time point?

The PrimeFaces documentation does indeed state on Page 309 of the 6.1 documentation
When working with forms and full page layout, avoid using a form that contains layoutunits as generated dom may not be the same. So following is
invalid.
And in that they reference your first example. It is technically not invalid but due to the way the layout component renders the html needed in the browser (and maybe client-side does dom manipulation) to get the good full page experience, it might (will? never tried it myself) result in unexpected behaviour.
They also state
A layout unit must have it’s own form instead, also avoid trying to update layout units because of same reason, update it’s content instead.
'Must have' (emphasis above is mine) is to strong here, they'd better have stated
give each layout unit its own form if a form is needed in the layout unit.
A full form around the full page layout might work now assuming the layout will not mess with things and e.g. add parts to the surrounding body tag (if it does do dom manipulation to achieve a certain behaviour), but I doubt they'd give you guarantees. An additional reason to not do it like you ask might be that you can run into nested forms when developers of 'partial pages' a not fully aware of the 'god form'. So I would advise against it.
So if e.g. the north and south layoutunit contain sort of fixed functionality (header with search, footer with some features) then put a h:form directly in the layout unit. If the center part contains dynamic things e.g. a ui:include, put the `h:form in the included parts.
See also:
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?
How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)

Related

How to hide some column in columns tag in primefaces?

I have a table which I want to hide particular column as below.
For example, I want to hide 3 last columns under the tag <p:columns> </p:columns>
<p:dataTable id="dynaDataTable" var="row" value="#{onListBean.rowList}" style="font-size:12px;"
selectionMode="single" selection="#{onListBean.selectedRow}" rowKey="#{row.s_nr}"
widgetVar="dynaTable" emptyMessage="Empty!" rowIndexVar="rowIndex"
scrollable="true" scrollHeight="100%">
<p:column id="rowNumber" exportable="false" headerText="#" style="max-width:50px; width:20px" >
<h:outputText value="#{rowIndex+1}" />
</p:column>
<p:columns headerText="#{column.header}" value="#{onListBean.columns}" var="column" >
<div style="text-align: center;">
<h:outputText value="#{row[column.property]}"/>
</div>
</p:columns> </p:dataTable>
Any Idea?
Just create a method in your bean which will return the columns you want to display, and use that with <p:columns value="...". If that is somehow not possible, you can also use the visible attribute, for example visible="#{column.header ne 'excludeMe'}".
If you are looking to display columns based on the available screen width, you should have a look at either the responsivePriority property, or <p:dataTable reflow="true".
See also:
https://www.primefaces.org/showcase/ui/data/datatable/responsive.xhtml
I couldn't understand from your question if you need it done using a UI component or not. If yes, Primefaces has a pretty nice component <p:columnToggler /> which lets you hide and show the table columns whenever you want.
If you were talking about the other scenario, I still think you could do some trick with columntoggler while not displaying it in the UI.

Include page with specific anchor

I'am a beginner in jsf and I want to open an html page in a p:dialog.
When I use the <ui: include> to display the page like this:
<p:dialog header="Dialog"
widgetVar="dlg"
resizable="false"
dynamic="true"
fitViewport="true">
<ui:include src="/resources/md.html" />
</p:dialog>
it works with no problem, but when I want to open the page in a specific anchor like this:
<p:dialog header="Dialog"
widgetVar="dlg"
resizable="false"
dynamic="true"
fitViewport="true">
<ui:include src="/resources/md.html#anchor" />
</p:dialog>
it doesn't work.
Can somebody help please.
Your attempt fails because your md.html is statically included inside 'parent' jsf page. Therefore only parent jsf page can be used to achieve 'go to anchor' functionality.
To achieve what you want with an included page inside p:dialog, I would use simple java script.
JS
Add this JS function to your parent jsf page (page where dialog is defined)
function gotoAnchor(anchorID) {
document.getElementById(anchorID).scrollIntoView();
}
XHTML
Add onShow attribute on p:dialog like this
<p:dialog ... onShow="gotoAnchor('anchorID')" ...>
<ui:include src="/resources/md.html" />
</p:dialog>
where anchorID is id of your anchor element inside md.html (in your example, its value is 'anchor').
On this way, when your p:dialog is shown, function gotoAnchor will be executed forcing page to scroll on required element.
This is another solution using iframe tag, it works perfectly:
<p:commandLink value="iframe" onclick="PF('dlg').show()" />
<p:dialog header="Dialog" widgetVar="dlg">
<iframe height="500" width="800" src="/md.xhtml#anchor"></iframe>
</p:dialog>
No js need.

primefaces 5.1.6 <p:printer> print datable formatting issues

Our project recently upgraded from primefaces v4.0.24 to primefaces v5.1.6.
Upon testing there it was found that when the datatable is printed to printer or PDF there were formatting issues. The column headers were not correctly justified especially the one having longer values.
However it fits correctly if I change the layout to landscape.
I want the data to be correctly justified in portrait mode.
This wasn't the problem with previous version of primefaces.
The page consists of commandlink and datatable.
When the user clicks on commandlink the id of the datatable is passed to p:printer.
Here is the code
<h:commandLink styleClass="ui-icon-export-print" title="#{webmsg['action.export.print.hint']}">
<p:printer target="companyTable" />
</h:commandLink>
<p:dataTable id="companyTable" widgetVar="companyTable" var="company" value="#{companies}"
sortBy="#{company.shortName}" sortOrder="ascending" filterEvent="enter"
filteredValue="#{companyForm.filteredCompanies}">
<f:facet name="header">
<h:outputText value="#{appmsg['label.companies']}" />
</f:facet>
<p:column sortBy="#{company.shortName}" filterBy="#{company.shortName}" filterMatchMode="contains" >
<f:facet name="header">
<h:outputText value="..." />
</f:facet>
<h:outputText value="#{company.shortName}" />
</p:column>
.....
</p:dataTable>
The data is either cuttoff or it touches the column border.
If I go to print options and change the default size of paper from A4 to Tabloid, then the data correctly fits within the column.
There should be some way to autofit the data with the default paper size.
Any ideas or clues to fix the formatting issue would be appreciated. Thanks.
Yes, you can use css for this. It has media types so you can tune things for just print devices and leave the screen things untouched. You can also change the ['paper size']there

JSF/ Styling h:outputText tooltip

I would like to create a custom look for a tooltip.
<h:outputText value="blarg" title="tooltip">
Plese do not tell me to use rich:tooltip as I have tried and they have a bug where it extends past a data table. So I was wondering if it is possible to actually style the jsf's outputText tooltip.
If you know how to, please give me pointers.
Thank you. Have a good day.
You cannot style a tooltip using plain vanilla HTML/CSS. You really need JavaScript for this as well which walks through the HTML DOM tree and "converts" every title attribute into some hidden fancy looking <div> which gets shown during onmouseover.
Since RichFaces already ships with jQuery, it should be possible to grab a jQuery plugin for that. For example, the qTip plugin.
Please do not tell me to use <rich:tooltip> as I have tried and they have a bug where it extends past a data table.
It should technically be a matter of finetuning the CSS associated with the <rich:tooltip>.
You can do this.
Use <p:tooltip/> of Primefaces.
View:
<h:panelGrid columns="2" cellpadding="10">
<h:outputLink styleClass="outputText" id="fades" value="#">
<h:outputText value="Your text"/>
</h:outputLink>
<p:tooltip id="toolTipFades" for="fades" value="The text for tooltip"/>
</h:panelGrid>
Css:
.outputText{
cursor: default!important;
text-decoration: none!important;
}
With this code you simulate a <h:outputText /> with a tooltip and works ;D

Primefaces Dialogs Form Structure

I'm using Primefaces for a project and I'm seeing bad results with IE vs chrome/firefox/safari in regards to modal Primefaces dialog windows and I think it has to do with form placement. In IE these dialogs dont appear, but I can see the transparency. In chrome/firefox they're fine. What is the best practice for the below situations:
List item base xhtml page that has one form. This page has several
links that open up dialogs who have their own ajax submit
(commandButton, commandLink) events.
Should the dialog be located within or outside the base xhtml page's form?
Should the dialog have its own form?
Below is an illustration:
<html>
<ui:composition>
<ui:define name="content">
<h:form id="xyz">
//main page content here, commandButtons, commandLinks...etc
</h:form>
<dc:zoomDialog/>
</ui:define>
</ui:composition>
</html>
<!-- zoomDialog maps to the below -->
<html>
<ui:component>
<h:form id="dialogFrm">
<p:dialog widgetVar="zoomDlg" modal="true" styleClass="dialog dialog2"
draggable="false" resizable="false" showEffect="fade"
hideEffect="fade">
//dialog content here, commandButton, commanLink...etc
</p:dialog>
</h:form>
</ui:component>
I don't see it in your example code but some time ago I had a similar problem. The reason was: nested forms (the same symptoms as you describe: all browser work, except IE). Nested forms are not valid html. Some browsers can handle it. IE cannot.
A good test is to put the whole html outpout (browser source, not the jsf source) into the W3C Html validator and analyze the results.
In the Primefaces showcase the h:form element is always inside the p:dialog. See this discussion.