Datatable paginator is not displayed - jsf

I am making a very simple datatable with JSF 2.0 tag dataTable but for some reason the page paginator is not displayed. Why is that?
<p:dataTable var="garbage" value="#{resultsController.allGarbage}" paginator="true" rows="10">
<p:column>
<f:facet name="header">
<h:outputText value="Filename" />
</f:facet>
<h:outputText value="#{garbage.filename}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Description" />
</f:facet>
<h:outputText value="#{garbage.description}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Upload date" />
</f:facet>
<h:outputText value="#{garbage.uploadDate}" />
</p:column>
</p:dataTable>

Use p:dataTable instead of h:dataTable.
The pagination only works with the primefaces dataTable and not with the plain jsf dataTable.

The paginatorAlwaysVisible is an attribute of the primefaces datatable implementation, so you would have to use the datatable tag from the primefaces namespace: p:dataTable.
Edit: Also, you need a h:head element defined in your page, so that the jsf impl knows where to output additional scripts and stylesheets. If that is the case you should be seeing an error message like:
One or more resources have the target of 'head', but no 'head' component has been defined within the view.
To help debuging you could add the following context parameter to your web.xml:
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>

#sfrj: You probably need something like this:
<p:dataTable var="garbage" value="#{resultsController.allGarbage}" paginator="true" rows="10" paginatorPosition="bottom" paginatorTemplate="{FirstPageLink} {PageLinks} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15,20" paginatorAlwaysVisible="false">
paginator="true" only tells the p:dataTable component that you want the paginator control but you haven't specified what you want in it yet. Hence, you need the paginatorTemplate attribute. The paginatorAlwaysVisible="false" attribute is good aesthetically if your query returns no record - in which case, the paginator section won't be shown if there are no record. Else, it's visible if there is at least one record returned from your query.

Related

primefaces editable datable with autocomplete stuck up on edit or edit cancel [duplicate]

I am using JSF 2.2 with Primefaces 5.1. There is an editable primefaces datatable with pagination enabled.
<p:dataTable editMode="row"
editable="true"
value="#{usersBean.users}"
var="user" paginator="true" rows="20">
<p:ajax event="rowEditInit" onstart="handleRowEditInit(event,this);"/>
<p:column>
<p:rowEditor/>
</p:column>
<p:column headerText="Real name">
<p:cellEditor rendered="true">
<f:facet name="input">
<p:inputText value="#{user.realName}"/>
</f:facet>
<f:facet name="output">
<h:outputText value="#{user.realName}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="User name">
<p:cellEditor>
<f:facet name="input">
<p:inputText value="#{user.userName}"/>
</f:facet>
<f:facet name="output">
<h:outputText value="#{user.userName}"/>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
Every time the page is changed the datatable does an AJAX POST with all the data of the current page. As you can partly see in the image below.
For big tables with much data this results in huge requests. This is not neccessary right? Is there a way to change this behavior?
Indeed, when you submit a form in HTML, by default every single HTML input element will be sent as request parameter. PrimeFaces ajax components therefore offer the partialSubmit="true" attribute which will then send only the HTML input elements covered by the process attribute, which defaults in <p:ajax> to #this and in <p:commandXxx> to #form.
So, just add this to the data table in case to optimize pagination performance:
<p:ajax event="page" partialSubmit="true" />
And add this to any command button which only needs to access the current row in the data table (e.g. to show it in a dialog) to optimize action processing performance:
<p:commandButton ... process="#this" partialSubmit="true" />
You can also configure it globally via below context param in web.xml:
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
And then for cases where you actually need a full submit, explicitly use partialSubmit="false".

How to have ajaxstatus only for particular primefaces livescroll datatable in a jsf page?

Hi guys I have two live scroll datatable in a same page once I scroll ajaxstatus is loading fine. But I want to implement ajax loading for the particular datatable live scroll process. For other events in the page ajaxloader should not load what to do ? I have included ajaxstatus in each datatable header. check the image for more clarity
<f:facet name="header">
<p:ajaxStatus style="float:right;margin-right: 3em;padding-top: 0.2em;">
<f:facet name="default">
<p:graphicImage value="/resources/images/login/loading.gif" />
</f:facet>
<f:facet name="start">
<p:graphicImage value="/resources/images/login/loading.gif" />
</f:facet>
<f:facet name="complete">
</f:facet>
</p:ajaxStatus>
</f:facet>

Wrong values in <p:rowExpansion> and empty values in <p:cellEditor> on scrolled page when using <p:dataTable lazy="true" liveScroll="true">

I am using JSF 2.2 with PrimeFaces 4.0. I have a <p:dataTable> with live scrolling, lazy loading, row-expansion and cell-editing, etc.
<p:dataTable
id="dtaTable"
selection="#{cont.selectedArray}"
resizableColumns="true"
draggableColumns="true"
var="dataModel"
value="#{cont.yieldBondsModel}"
editable="true"
editMode="cell"
selectionMode="multiple"
rowSelectMode="add"
scrollable="true"
scrollHeight="650"
rowKey="#{modeld.id}+#{model.name}"
rowIndexVar="rowIndex"
filterEvent="enter"
styleClass="screenScrollStyle"
scrollRows="25"
liveScroll="true"
lazy="true"
rows="50"
filteredValue="#{cont.filteredModel}"
widgetVar="dt4"
>
<p:rowExpansion>
<h:panelGrid id="display" columns="2" cellpadding="4" style="width:300px;" styleClass="ui-widget-content grid">
<f:facet name="header" styleClass="dataTableHeader">Other Data</f:facet>
<h:outputText value="id " />
<h:outputText value="#{dataModel.id}"/>
<h:outputText value="Name" />
<h:outputText value="#{dataModel.name}" />
</h:panelGrid>
</p:rowExpansion>
<p:column width="15">
<p:rowToggler />
</p:column>
...
</p:dataTable>
On the first page everything works like a charm. Once I scroll it down, data is getting lazy-loaded perfectly fine, but it has some problems during row-expansion and cell-editing:
In row-expansion, I am getting wrong values. Maybe overlapped values from other row.
Cell-editing is also not working. Once I edit any cell, values are not getting displayed in cell-editor. I have checked in Firebug, there is no value in <h:outputText> as confirmed by the generated HTML <div class="ui-cell-editor-output" style="display: none;"></div>. As you can see, there is no value inside the div.
The backing bean is #SessionScoped.
How is this caused and how can I solve it?
This is a known issue on PrimeFaces, and already reported and fixed in Elite version (4.0.7 if I remember well). However community release does not contain this fix yet. There is an RC for PrimeFaces 5.0 which contains this fix. You can download it and test if it's suits for you needs, but be aware that this is only a release candidate, not a final release. AFAIK the ETA for the 5.0 final is the first half of May.

JSF/PrimeFaces - Approaches for creating reusable data table dialogs

I am using JSF 2.0 with Primefaces. I have a page with a data table containing a list of users in the system. Each user can have a collection of roles, so i would like to have a button to select a bunch of roles. I wanted this to be an ajax selector and reusable from other pages, so this is how i have laid it out.
User List page
<h:form prependId="false">
<p:dataTable id="userList" var="user" value="#{userBean.users}">
<p:column id="modelHeader">
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{user.name}" />
</p:column>
<p:column>
<f:facet name="header">
Select Roles
</f:facet>
<p:commandButton id="selectButton" oncomplete="roleDialog.show()" icon="ui-icon-search" title="Select Roles" />
</p:column>
</p:dataTable>
</h:form>
Dialog defined inside user list page, but the contents will be moved to an include to promote reusability
<p:dialog header="Roles" widgetVar="roleDialog" resizable="true" id="roleDialog" modal="true">
<h:form prependId="false">
<h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">
<p:dataTable id="roleList" var="user" value="#{roleBean.roles}">
<p:column id="modelHeader">
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{role.name}" />
</p:column>
<p:commandButton id="selectButton" actionListener="#{roleBean.selectRoles}" title="Select Roles" />
</h:panelGrid>
</h:form>
</p:dialog>
My question is, I am not sure how to achieve the following.
I would like to pass arguments to the role selector as criteria before rendering the content in the dialog.I can do this via f:setPropertyActionListener.. correct?
After the role is selected, i would like to pass the selected id back to the user list page. I can do this via addCallbackParam, correct?
Then i would like to pass that value back into the userList bean to an action listener to associate this role(s) to the user
What is the best pattern to achieve this workflow in JSF. I do not want to duplicate my role selector in each page as i would like to re-use that.
Thank you for your patience in reading through this long post. I appreciate your response and
suggestions.
The best pattern for this would be to implement a composite component.

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>

Resources