I'm not sure if this is a bug or just something that isn't implemented but I can't update the dataGrids page property to reset the pagination to page 1. I've bound it to an expression in my bean and update it via an ajax update, but it doesn't get updated when I clicked my button. The paginator will stay on the selected page and not reset via an ajax request. I'm using to try to reset it. The dreamSearchBean's setCurrentPage does get called and gets passed 1 but it stays at whatever page was last selected
<h:form id="dreamWebSearchFrm">
<p:commandButton styleClass="form-btn1" value="#{bundle['dreamSearch.search.button.TEXT']}" onclick="trackingDreamSearch()"
actionListener="#{dreamSearch.search}" update=":dreamWebSearchFrm:resultsPnl">
<f:setPropertyActionListener value="1" target="#{dreamSearchBean.currentPage}"/>
</p:commandButton>
<p:panel id="resultsPnl">
<div class="data-grid-wrap"开发者_如何学运维>
<h:outputFormat escape="false" value="#{bundle['dreamSearch.imageResults.TEXT']}" rendered="#{dreamSearchBean.shouldRender}" >
<f:param value="#{dreamSearchBean.searchText}" />
</h:outputFormat>
<p:dataGrid var="dream" value="#{dreamSearchBean.dreams}" rendered="#{dreamSearchBean.shouldRender}" page="#{dreamSearchBean.currentPage}" pageLinks="3" columns="4" rows="4" paginator="true" effect="true"
styleClass="ui-header-visibility"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
paginatorPosition="bottom">
<p:column>
<h:panelGrid columns="1">
<p:commandLink onclick="webSearchDlg.hide();dreamEditDlg.show();" update=":dreamEditFrm:display">
<f:setPropertyActionListener value="#{dream}" target="#{dreamModifyBean.selectedDream}"/>
<p:graphicImage value="#{dream.imageThumb}" width="125" height="100"></p:graphicImage>
</p:commandLink>
</h:panelGrid>
</p:column>
</p:dataGrid>
</div>
</p:panel>
</h:form>
Using Primefaces 3.2 I get a similar problem when I do a query and when I get, for example, five pages, then I do a new query and the page count would be 10 but it will default to the previous query and stay a page 5. The solution to reset to page one is below:
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("documentSearch:searchFormCase:documentSearchTable");
dataTable.setFirst(0);
Even though I am using:
import org.primefaces.component.datatable.DataTable;
It should work on the component below:
import org.primefaces.component.datagrid.DataGrid;
You have to extend the DataTableRenderer of Primefaces. Create a new class, maybe it could be DataTableRendererExt that extends the DataTableRenderer.
Override the encodeMarkup(...)
method, copy the origin code, and insert a call to resetPagination()
:
@Override
protected void encodeMarkup(FacesContext context, DataTable table) throws IOException{
ResponseWriter writer = context.getResponseWriter();
...
if(hasPaginator) {
table.resetPagination();
table.calculatePage();
}
To bind this extended class in your application you have to insert this block in your faces-config.xml:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.DataTableRenderer</renderer-type>
<renderer-class>your.package.DataTableRendererExt</renderer-class>
</renderer>
</render-kit>
There is another bug in the DataTableRenderer - lazyLoading. Data table is empty on the very first load because of incorrect placement of table.loadLazyData()
in the encodeTbody(...)
method.
Here is my code for the extension class:
public class DataTableRendererExt extends DataTableRenderer
{
@Override
protected void encodeMarkup(FacesContext context, DataTable table) throws IOException{
ResponseWriter writer = context.getResponseWriter();
String clientId = table.getClientId(context);
boolean scrollable = table.isScrollable();
String containerClass = scrollable ? DataTable.CONTAINER_CLASS + " " + DataTable.SCROLLABLE_CONTAINER_CLASS : DataTable.CONTAINER_CLASS;
containerClass = table.getStyleClass() != null ? containerClass + " " + table.getStyleClass() : containerClass;
String style = null;
boolean hasPaginator = table.isPaginator();
String paginatorPosition = table.getPaginatorPosition();
if(hasPaginator) {
table.resetPagination();
table.calculatePage();
}
writer.startElement("div", table);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("class", containerClass, "styleClass");
if((style = table.getStyle()) != null) {
writer.writeAttribute("style", style, "style");
}
encodeFacet(context, table, table.getHeader(), DataTable.HEADER_CLASS);
if(hasPaginator && !paginatorPosition.equalsIgnoreCase("bottom")) {
encodePaginatorMarkup(context, table, "top");
}
if(scrollable) {
encodeScrollableTable(context, table);
} else {
encodeRegularTable(context, table);
}
if(hasPaginator && !paginatorPosition.equalsIgnoreCase("top")) {
encodePaginatorMarkup(context, table, "bottom");
}
encodeFacet(context, table, table.getFooter(), DataTable.FOOTER_CLASS);
if(table.isSelectionEnabled()) {
encodeSelectionHolder(context, table);
}
writer.endElement("div");
}
/**
* @see org.primefaces.component.datatable.DataTableRenderer#encodeTbody(javax.faces.context.FacesContext, org.primefaces.component.datatable.DataTable)
* Fix for lazy load bug: data table is empty on very first load because of wrong palcement of table.loadLazyData();
*/
@Override
protected void encodeTbody(FacesContext context, DataTable table) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String rowIndexVar = table.getRowIndexVar();
String clientId = table.getClientId(context);
String emptyMessage = table.getEmptyMessage();
String selectionMode = table.getSelectionMode();
String columnSelectionMode = table.getColumnSelectionMode();
String selMode = selectionMode != null ? selectionMode : columnSelectionMode != null ? columnSelectionMode : null;
Object selection = table.getSelection();
if(table.isLazy()) {
table.loadLazyData();
}
int rows = table.getRows();
int first = table.getFirst();
int rowCount = table.getRowCount();
int rowCountToRender = rows == 0 ? rowCount : rows;
boolean hasData = rowCount > 0;
String tbodyClass = hasData ? DataTable.DATA_CLASS : DataTable.EMPTY_DATA_CLASS;
writer.startElement("tbody", null);
writer.writeAttribute("id", clientId + "_data", null);
writer.writeAttribute("class", tbodyClass, null);
if(hasData) {
if(selectionMode != null && selection != null) {
handlePreselection(table, selectionMode, selection);
}
for(int i = first; i < (first + rowCountToRender); i++) {
encodeRow(context, table, clientId, i, rowIndexVar);
}
}
else if(emptyMessage != null){
//Empty message
writer.startElement("tr", null);
writer.writeAttribute("class", DataTable.ROW_CLASS, null);
writer.startElement("td", null);
writer.writeAttribute("colspan", table.getColumns().size(), null);
writer.write(" ");
writer.endElement("td");
writer.endElement("tr");
}
writer.endElement("tbody");
//Cleanup
table.setRowIndex(-1);
if(rowIndexVar != null) {
context.getExternalContext().getRequestMap().remove(rowIndexVar);
}
}
}
I have done something like this (for primefaces 3.4.2)
widgetVar.getPaginator().setPage(0)
and my button
<p:commandButton value="Search" update=":tableForm:dataTable" onclick="dataTable.getPaginator().setPage(0)"/>
and my table
<h:form id="tableForm">
<p:dataTable id="dataTable" var="..." value="#{...}" widgetVar="dataTable" ...
I never used it but in Primefaces documentation there is an attribute page
for p:dataGrid
. The description is the following:
Index of the current page, first page is 1 (type: Integer, default: 1)
Maybe you can use an el expression and reset the value from your backing bean when a new search is started:
<p:dataGrid var="dream" value="#{dreamSearchBean.dreams}"
...
paginatorPosition="bottom"
page=#{dreamSearchBean.currentPage}>
Your problem could be solved by the same solution as it was in my case (I want to reset the dataTable completely):
How to restore the state of p:dataTable before dialog reopen?
You need to declare component binding, and you will have DataTable set in your bean:
private DataTable tableBinding;
Now you can invoke any operation you want, that is missing in JavaScript API (I think that it should be available to JavaScript API anyway, but we have no influence on that).
In PF 4.0 i use this
DataGrid dataGrid = (DataGrid) FacesContext.getCurrentInstance().getViewRoot().findComponent("formEventList:eventsList");
dataGrid.setFirst(0);
DataGrid don't have reset() function like DataTable.
精彩评论