-
1. Re: Sort & Filter using ExtendedDataModel/Arrangeable affecting all other Data Iteration components in same page
snjv180 Sep 19, 2012 3:48 AM (in response to cseabra)I think you may use limitrender attribute to stop this behaviour. I think you may be rendering a parent component and this has made changes to all of the child components as well.
-
2. Re: Sort & Filter using ExtendedDataModel/Arrangeable affecting all other Data Iteration components in same page
cseabra Sep 19, 2012 9:50 AM (in response to snjv180)I put limitrender where possible and the result was still the same.
See my code:
index.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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:c="http://java.sun.com/jsp/jstl/"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich" template="/templates/main.xhtml">
<ui:define name="content">
<h:form id="formBooking">
<rich:popupPanel id="panelModal" width="350" height="100"
modal="true">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Editando ..."></h:outputText>
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:graphicImage library="default" name="img/close.png"
style="cursor:pointer"
onclick="#{rich:component('panelModal')}.hide()" />
</f:facet>
<h:outputText value="Será implementado em breve"></h:outputText>
</rich:popupPanel>
<a4j:outputPanel ajaxRendered="true">
<h:messages />
</a4j:outputPanel>
<div class="box-search">
<h:panelGrid columns="6">
<h:outputText value="CLIENTE" />
<h:inputText id="cadimpCode" size="8"
value="#{bookingController.cadimpCode}" readonly="true" />
<rich:autocomplete id="autoCompleteName"
autocompleteMethod="#{bookingController.loadCadimpsByName}"
var="cadimpName" converter="cadimpConverter"
fetchValue="#{cadimpName}" minChars="4"
value="#{bookingController.selectedCadimp}"
onselectitem="selectingCadimp()" style="margin:2px;padding:1px;"
inputClass="autocomplete-cadimp"
popupClass="autocomplete-cadimp-popup">
${cadimpName}
</rich:autocomplete>
<a4j:jsFunction name="selectingCadimp" execute="autoCompleteName"
render="cadimpCode" />
<a4j:commandButton value="Pesquisar"
action="#{bookingController.setLoadBookinksToTrue}">
<a4j:ajax event="click" render="panelTabs previsao atracadas" execute="@this" limitRender="true"/>
</a4j:commandButton>
<h:button value="Limpar" />
</h:panelGrid>
</div>
<rich:panel id="panelTabs"
style="border: 0px; margin: 0px; padding: 0px;">
<rich:tabPanel id="tabs">
<rich:tab header="Pesquisar" headerStyle="padding: 5px;">
<f:facet name="header">
<h:graphicImage library="default" name="img/find.png" />
</f:facet>
</rich:tab>
<!-- ======= PREVISAO DE EMBARQUE ======= -->
<rich:tab
header="PREVISÃO DE EMBARQUE(#{bookingController.bookingsPrevisaoDeEmbarqueTabRowCount})"
headerStyle="padding: 5px;">
<ui:include src="includes/bookingTable.xhtml">
<ui:param name="bookings"
value="#{bookingController.bookingsPrevisaoDeEmbarqueTab}" />
<ui:param name="tableId" value="previsao" />
<ui:param name="sortOrder"
value="#{bookingController.sortOrdersPrevisaoDeEmbarque}" />
</ui:include>
</rich:tab>
<!-- ======= CARGAS EMBARCADAS ======= -->
<rich:tab
header="CARGAS EMBARCADAS(#{bookingController.bookingsCargasEmbarcadasTabRowCount})"
headerStyle="padding: 5px;">
<ui:include src="includes/bookingTable.xhtml">
<ui:param name="bookings"
value="#{bookingController.bookingsCargasEmbarcadasTab}"></ui:param>
<ui:param name="tableId" value="embarcadas"></ui:param>
<ui:param name="sortOrder"
value="#{bookingController.sortOrdersCargasEmbarcadas}"></ui:param>
</ui:include>
</rich:tab>
<!-- ======= CARGAS LIBERADAS ======= -->
<rich:tab header="CARGAS LIBERADAS(X)" headerStyle="padding: 5px;"></rich:tab>
<rich:tab header="IMPRIMIR" headerStyle="padding: 5px;">
<f:facet name="header">
<h:graphicImage library="default" name="img/printer.png" />
</f:facet>
</rich:tab>
<rich:tab header="SALVAR" headerStyle="padding: 5px;">
<f:facet name="header">
<h:graphicImage library="default" name="img/disk.png" />
</f:facet>
</rich:tab>
</rich:tabPanel>
</rich:panel>
</h:form>
</ui:define>
</ui:composition>
bookingTable.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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:c="http://java.sun.com/jsp/jstl/"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<rich:extendedDataTable value="#{bookings}" var="bookingItem" rows="10"
id="${tableId}">
<rich:column>
<h:commandLink>
<h:graphicImage library="default" name="img/page_edit.png" />
<rich:componentControl target="panelModal" operation="show" />
</h:commandLink>
</rich:column>
<ui:param name="propertyRef" value="ref" />
<rich:column sortBy="${propertyRef}"
sortOrder="#{sortOrder[propertyRef]}">
<f:facet name="header">
<h:outputText value="REF" />
<h:commandLink action="#{bookingController.toggleSort}">
#{sortOrder[propertyRef]}
<a4j:ajax render="${tableId}" execute="@this" limitRender="true"/>
<f:setPropertyActionListener
target="#{bookingController.sortProperty}" value="ref" />
<f:setPropertyActionListener
target="#{bookingController.currentSortOrder}" value="${sortOrder}" />
</h:commandLink>
</f:facet>
<h:outputText value="#{bookingItem.ref}" />
</rich:column>
<ui:param name="propertyDtInformacao" value="dtInformacao" />
<rich:column sortBy="#{propertyDtInformacao}"
sortOrder="#{sortOrder[propertyDtInformacao]}">
<f:facet name="header">
<h:outputText value="ATUALIZACAO" />
<h:commandLink action="#{bookingController.toggleSort}">
#{sortOrder[propertyDtInformacao]}
<a4j:ajax render="${tableId}" execute="@this" limitRender="true"/>
<f:setPropertyActionListener
target="#{bookingController.sortProperty}" value="dtInformacao" />
<f:setPropertyActionListener
target="#{bookingController.currentSortOrder}" value="${sortOrder}" />
</h:commandLink>
</f:facet>
<h:outputText value="#{bookingItem.dtInformacao}" />
</rich:column>
<f:facet name="footer">
<rich:dataScroller for="${tableId}" limitRender="true" />
</f:facet>
</rich:extendedDataTable>
</ui:composition>
BaseHibernateExtendedDataModel.java
package br.com.*******.web.datamodels;
import javax.faces.context.FacesContext;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.richfaces.component.SortOrder;
import org.richfaces.model.Arrangeable;
import org.richfaces.model.ArrangeableState;
import org.richfaces.model.FilterField;
import org.richfaces.model.SortField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
extends ExtendedDataModel implements Arrangeable {
private static Logger log = LoggerFactory
.getLogger(BaseHibernateExtendedDataModel.class);
protected SequenceRange cachedRange;
protected Integer cachedRowCount;
protected List cachedItems;
protected IQueryAbleType queryAbleType;
protected Object[] restrictionsValues;
private List filterFields;
private List sortFields;
private Object rowKey;
public BaseHibernateExtendedDataModel(IQueryAbleType queryAbleType,
Object... restrictionsValues) {
super();
this.queryAbleType = queryAbleType;
this.restrictionsValues = restrictionsValues;
}
protected static boolean areEqualsRanges(SequenceRange range1,
SequenceRange range2) {
if (range1 == null || range2 == null)
return (range1 == null && range2 == null);
else
return (range1.getFirstRow() == range2.getFirstRow() && range1
.getRows() == range2.getRows());
}
@Override
public Object getRowKey() {
return rowKey;
}
@Override
public void setRowKey(Object arg0) {
rowKey = arg0;
}
@SuppressWarnings(\"unchecked\")
@Override
public void walk(FacesContext context, DataVisitor visitor, Range range,
Object argument) {
SequenceRange sequenceRange = (SequenceRange) range;
if (this.cachedItems == null
|| !areEqualsRanges(this.cachedRange, sequenceRange)) {
Criteria criteria = this.queryAbleType
.getCriteria(this.restrictionsValues);
if (sequenceRange != null) {
int first = sequenceRange.getFirstRow();
int rows = sequenceRange.getRows();
criteria.setFirstResult(first);
if (rows > 0) {
criteria.setMaxResults(rows);
}
log.info(\"Specifying offset = \" + first + \" and limit = \"
+ rows);
}
appendSorts(context, criteria);
appendFilters(context, criteria);
this.cachedRange = sequenceRange;
log.info(\"Quering database\");
this.cachedItems = criteria.list();
}
for (I item : this.cachedItems) {
visitor.process(context, item.getId(), argument);
}
}
@Override
public int getRowCount() {
if (this.cachedRowCount == null) {
Criteria criteria = queryAbleType
.getCriteria(this.restrictionsValues);
appendFilters(FacesContext.getCurrentInstance(), criteria);
log.info(\"Getting row count\");
this.cachedRowCount = ((Long) criteria.setProjection(
Projections.rowCount()).uniqueResult()).intValue();
log.info(\"cachedRowCount setted to \" + this.cachedRowCount);
}
return cachedRowCount;
}
@Override
public I getRowData() {
for (I item : cachedItems) {
if (item.getId().equals(this.getRowKey()))
return item;
}
return null;
}
private int rowIndex;
private ArrangeableState arrangeableState;
@Override
public int getRowIndex() {
return rowIndex;
}
@Override
public boolean isRowAvailable() {
return (getRowData() != null);
}
@Override
public void setRowIndex(int arg0) {
rowIndex = arg0;
}
@Override
public void setWrappedData(Object arg0) {
throw new UnsupportedOperationException();
}
@Override
public Object getWrappedData() {
throw new UnsupportedOperationException();
}
@Override
public void arrange(FacesContext context, ArrangeableState state) {
if (state != null) {
//TODO
// if (arrangeableState != null) {
// if (stateAreEquals(arrangeableState, state)) {
// return;
// }
// }
//arrangeableState = state;
filterFields = state.getFilterFields();
sortFields = state.getSortFields();
cachedItems = null;
cachedRange = null;
cachedRowCount = null;
}
}
private void appendFilters(FacesContext context, Criteria criteria) {
if (filterFields != null) {
for (FilterField filterField : filterFields) {
String propertyName = getPropertyName(context,
filterField.getFilterExpression());
String filterValue = (String) filterField.getFilterValue();
if (filterValue != null && filterValue.length() != 0) {
log.info(\"Adding filter filterField\\\"\" + filterField
+ \"\\\", filterValue: \" + filterValue);
criteria.add(Restrictions.like(propertyName, filterValue,
MatchMode.ANYWHERE).ignoreCase());
}
}
}
}
private void appendSorts(FacesContext context, Criteria criteria) {
if (sortFields != null) {
for (SortField sortField : sortFields) {
SortOrder ordering = sortField.getSortOrder();
if (SortOrder.ascending.equals(ordering)
|| SortOrder.descending.equals(ordering)) {
String propertyName = getPropertyName(context,
sortField.getSortBy());
Order order = SortOrder.ascending.equals(ordering) ? Order
.asc(propertyName) : Order.desc(propertyName);
log.info(\"Adding order:\" + order);
criteria.addOrder(order);
}
}
}
}
private static String getPropertyName(FacesContext context,
ValueExpression expression) {
return (String) ((ValueExpression) expression).getValue(context
.getELContext());
}
} -
3. Re: Sort & Filter using ExtendedDataModel/Arrangeable affecting all other Data Iteration components in same page
cseabra Sep 19, 2012 10:58 AM (in response to cseabra)I solve my problem implementing:
stateAreEquals(ArrangeableState state1, ArrangeableState state2)
and calling this in "arrange(FacesContext context, ArrangeableState state)"
public void arrange(FacesContext context, ArrangeableState state) {
if (state != null) {
if (arrangeableState != null) {
if (stateAreEquals(arrangeableState, state)) {
return;
}
}
filterFields = state.getFilterFields();
sortFields = state.getSortFields();
cachedItems = null;
cachedRange = null;
cachedRowCount = null;
}
} -
4. Re: Sort & Filter using ExtendedDataModel/Arrangeable affecting all other Data Iteration components in same page
snjv180 Sep 19, 2012 11:22 PM (in response to cseabra)Good to know that you solved it.
-Sanjeev