Hello, I need help in order to implement a scrolling [b]combined with a[/b] sorting strategy for a datatable.
Here is the behaviour I need: A user should be able to scroll a datatable in steps of [b]N[/b] records. He/she should then be able to sort that [b]N[/b] records and not the whole of the resultset. My problem is that I copied and pasted code in order to implement the sorting strategy and then copied and pasted code in order to implement the scrolling strategy and now I have the following behavior: the user can scroll but when he/she attempts to sort, the whole of the resultset is sorted and records not belonging to the "page" (of N records) are displayed. Here is the Datamodel: [code] package com.calyonfinancial.protide; import com.calyonfinancial.protide.entities.Protide01p; import java.util.Arrays; import java.util.Comparator; import java.util.List; import javax.faces.model.DataModel; import javax.faces.model.DataModelListener; /** * * @author Julien Martin */ public class SortFilterModel extends DataModel{ private DataModel model; private Row[] rows; public SortFilterModel() { this((List<Protide01p>)null); } public SortFilterModel(List<Protide01p> list){ setWrappedData(list); } public SortFilterModel(DataModel model){ this.model = model; initializeRows(); } public void setRowIndex(int rowIndex) { if(rowIndex == -1||rowIndex>=model.getRowCount()){ model.setRowIndex(rowIndex); } else{ model.setRowIndex(rows[rowIndex].row); } } public int getRowCount() { return model.getRowCount(); } public Object getRowData() { return model.getRowData(); } public int getRowIndex() { return model.getRowIndex(); } public Object getWrappedData() { return model.getWrappedData(); } public boolean isRowAvailable() { return model.isRowAvailable(); } public void setWrappedData(Object object) { model.setWrappedData(object); } public void addDataModelListener(DataModelListener listener){ model.addDataModelListener(listener); } public DataModelListener[] getDataModelListeners(){ return model.getDataModelListeners(); } public void removeDataModelListener(DataModelListener listener){ model.removeDataModelListener(listener); } private void initializeRows(){ int rowCnt = model.getRowCount(); if(rowCnt!=-1){ rows = new Row[rowCnt]; for(int i = 0; i< rowCnt; ++i){ rows[i]= new Row(i); } } } public String sortByID(){ Arrays.sort(rows,byID); return null; } public String sortByIsin(){ Arrays.sort(rows,byISIN); return null; } public String sortByEquityDate(){ Arrays.sort(rows,byEquityDate); return null; } private static Comparator<Row> byID = new Comparator<Row>(){ public int compare(Row r1, Row r2){ Protide01p p1 = (Protide01p) r1.getData(); Protide01p p2 = (Protide01p) r2.getData(); return new Integer(p1.getTrOrderid()).compareTo(new Integer( p2.getTrOrderid())); } }; private static Comparator<Row> byISIN = new Comparator<Row>(){ public int compare(Row r1, Row r2){ Protide01p p1 = (Protide01p) r1.getData(); Protide01p p2 = (Protide01p) r2.getData(); return p1.getIsin().compareTo(p2.getIsin()); } }; private static Comparator<Row> byEquityDate = new Comparator<Row>(){ public int compare(Row r1, Row r2){ Protide01p p1 = (Protide01p) r1.getData(); Protide01p p2 = (Protide01p) r2.getData(); return p1.getEquityDate().compareTo(p2.getEquityDate()); } }; private class Row{ private int row; public Row(int row){ this.row = row; } public Object getData(){ int originalIndex = model.getRowIndex(); model.setRowIndex(row); Object thisRowData = model.getRowData(); model.setRowIndex(originalIndex); return thisRowData; } } } [/code] The code for the managed bean is as follows: [code] package com.calyonfinancial.protide; import com.calyonfinancial.protide.entities.Protide01p; import com.calyonfinancial.protide.persistence.PopulateUtil; import java.util.List; import javax.faces.model.DataModel; import javax.faces.model.ListDataModel; import org.apache.log4j.Logger; /** * * @author Julien Martin */ public class Protide01pManagedBean { private static Logger log = Logger.getLogger(" com.calyonfinancial.protide"); private PopulateUtil pu = new PopulateUtil(); private List<Protide01p> lines; private int lineCount; private int firstRowIndex; private int numberOfRows = 10; private SortFilterModel protide01pModel = null; public Protide01pManagedBean() { setLines(pu.populateLinesOfProtide01p());//todo! might not need mutator for lines setLineCount(lines.size()); protide01pModel = new SortFilterModel(new ListDataModel(lines)); } // public List<Protide01p> getLines() { // return lines; // } public SortFilterModel getLines(){ return protide01pModel; } public void setLines(List<Protide01p> lines) { this.lines = lines; } public int getLineCount() { return lineCount; } public void setLineCount(int lineCount) { this.lineCount = lineCount; } public int getFirstRowIndex() { return firstRowIndex; } public void setFirstRowIndex(int firstRowIndex) { this.firstRowIndex = firstRowIndex; } public int getNumberOfRows() { return numberOfRows; } public void setNumberOfRows(int numberOfRows) { this.numberOfRows = numberOfRows; } public String scrollNext(){ firstRowIndex += numberOfRows; if (firstRowIndex >= protide01pModel.getRowCount()){ firstRowIndex = protide01pModel.getRowCount() - numberOfRows; if(firstRowIndex<0){ firstRowIndex = 0; } } return null; } public String scrollPrevious(){ firstRowIndex -= numberOfRows; if(firstRowIndex<0){ firstRowIndex = 0; } return null; } } [/code] Here are the relevant snippets from my JSPs: [code] <h:dataTable id="protidedatatable" first="#{ Protide01pManagedBean.firstRowIndex}" rows="#{ Protide01pManagedBean.numberOfRows}" value="#{Protide01pManagedBean.lines}" var="line" styleClass="table" headerClass="th" columnClasses="td" rowClasses="whiteRow,greyRow" width="100%" binding="#{ ContractManagedBean.protide01p}"> ... <h:commandButton value="previous" immediate="true" action="#{ Protide01pManagedBean.scrollPrevious}"/> <h:commandButton value="next" immediate="true" action="#{ Protide01pManagedBean.scrollNext}"/> [/code] I am at a loss on how to proceed in order to make it work. Can anyone help please? Thanks in advance, Julien.