You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Julien Martin <ba...@gmail.com> on 2007/08/23 10:45:26 UTC
Scrolling + sorting a datatable
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.
Re: Scrolling + sorting a datatable
Posted by Mike Kienenberger <mk...@gmail.com>.
To me it sounds like you need to change how your data model is
provided to your table.
I think the most reasonable approach is to set the backing model of
the table to only include your current scroll set, then you can use a
"standard" sorting model for your table. So each change of the
scroll set would reset the table model to a new subset of the full
data set.
Otherwise, you have to make your Sort model aware of the current
scroll set, which sounds like a much more difficult problem.
By the way, there's a Comparator-driven BaseSortableDataModel in
MyFaces that you might find useful. I suspect it's similar to the
sort model class you have below.
http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/ext/BaseSortableModel.java?view=markup
http://mail-archives.apache.org/mod_mbox/myfaces-dev/200703.mbox/%3c8f985b960703300919g34407a9fh74db06397f139959@mail.gmail.com%3e
On 8/23/07, Julien Martin <ba...@gmail.com> wrote:
> 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.
>
>