-
1. Re: How to load rows on demand using rich:scrollabledatatable
richdeveloper Oct 6, 2011 10:23 PM (in response to richdeveloper)OK.
Finally I learned that just using "rows" attribute in rich:scrollableDataTable is not enough, one MUST implement ScrollableTableDataModel class and override loadData() method. So following is the code snippet:
<rich:scrollableDataTable id="listId" value="#{jobRows}" var="jobListRow"
rendered="true" rowClasses="even-row, odd-row" rows="50" height="400px"
rowKeyVar="row" ignoreDupResponses="true" style="z-index:-1;width:100%;">
<rich:column label="Id" sortBy="#{jobListRow.jobId}"
sortOrder="UNSORTED" width="100px" sortMode="multy">
Following in for ScrollableDataModel ....
package com.xyz.action;
import static org.jboss.seam.ScopeType.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.richfaces.model.ScrollableTableDataModel;
import org.richfaces.model.SortOrder;
import com.xyz.model.StatusType;
import com.xyz.session.manager.JobManager;
@Name(value = "jobScrollableDataModel")
@Scope(SESSION)
public class JobScrollableDataModel extends ScrollableTableDataModel implements java.io.Serializable
{
private static final Logger logger = Logger.getLogger(JobScrollableDataModel.class);
private static final long serialVersionUID = 1L;
private List<StatusType> selectedStatusTypes;
private String fileSearchName = null;
private Integer jobId = null;
private Date fromDate;
private Date toDate;
private List<JobRow> jobRows;
@In
private JobManager jobManager;
@In
protected FacesMessages facesMessages;
Map rangeMap = new HashMap();
boolean render = false;
int numberOfRows = 0;
/**
* @return the selectedStatusTypes
*/
public List<StatusType> getSelectedStatusTypes()
{
return selectedStatusTypes;
}
/**
* @param selectedStatusTypes the selectedStatusTypes to set
*/
public void setSelectedStatusTypes(List<StatusType> selectedStatusTypes)
{
this.selectedStatusTypes = selectedStatusTypes;
}
/**
* @return the fileSearchName
*/
public String getFileSearchName()
{
return fileSearchName;
}
/**
* @param fileSearchName the fileSearchName to set
*/
public void setFileSearchName(String fileSearchName)
{
this.fileSearchName = fileSearchName;
}
/**
* @return the jobId
*/
public Integer getJobId()
{
return jobId;
}
/**
* @param jobId the jobId to set
*/
public void setJobId(Integer jobId)
{
this.jobId = jobId;
}
/**
* @return the fromDate
*/
public Date getFromDate()
{
return fromDate;
}
/**
* @param fromDate the fromDate to set
*/
public void setFromDate(Date fromDate)
{
this.fromDate = fromDate;
}
/**
* @return the toDate
*/
public Date getToDate()
{
return toDate;
}
/**
* @param toDate the toDate to set
*/
public void setToDate(Date toDate)
{
this.toDate = toDate;
}
/* (non-Javadoc)
* @see org.richfaces.model.ScrollableTableDataModel#loadData(int, int, org.richfaces.model.SortOrder)
*/
@Override
public List<JobRow> loadData(int arg0, int arg1, SortOrder arg2)
{
try
{
if (selectedStatusTypes == null || selectedStatusTypes.isEmpty())
{
this.setJobRows( new ArrayList<JobRow>());
this.render = false;
}
else
{
// rangeMap.put(arg0, arg1);
// if(!rangeMap.containsKey(arg0))
// {
this.setJobRows( new ArrayList<JobRow>());
jobRows = jobManager.getListOfJobs(selectedStatusTypes,fileSearchName,fromDate,toDate,jobId,arg0,arg1,false);
int totalRows = jobRows.size();
if(totalRows > 0)
{
this.render = true;
}
else
{
this.render = false;
}
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return jobRows;
}
/* (non-Javadoc)
* @see javax.faces.model.DataModel#getRowCount()
*/
@Override
public int getRowCount()
{
return getTotalCount();
}
/* (non-Javadoc)
* @see javax.faces.model.DataModel#getWrappedData()
*/
@Override
public Object getWrappedData()
{
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see javax.faces.model.DataModel#setWrappedData(java.lang.Object)
*/
@Override
public void setWrappedData(Object arg0)
{
throw new UnsupportedOperationException();
}
public int getTotalCount()
{
int count = 0;
try
{
count = jobManager.getTotalCountOfJobs(selectedStatusTypes, fileSearchName, fromDate, toDate);
if(count == 0)
{
this.render = false;
}
}
catch (Exception e)
{
e.printStackTrace();
}
this.setNumberOfRows(count);
return count;
}
/**
* @return the jobRows
*/
public List<JobRow> getJobRows()
{
return jobRows;
}
/**
* @param jobRows the jobRows to set
*/
public void setJobRows(List<JobRow> jobRows)
{
this.jobRows = jobRows;
}
public void clear()
{
try
{
logger.trace("clearing joblist !!");
//clear the form data
this.selectedStatusTypes = new ArrayList<StatusType>();
this.fromDate = null;
this.toDate = null;
this.fileSearchName = null;
this.jobId = null;
this.render = false;
}
catch (Exception e)
{
logger.error("Problem with clear.", e);
}
}
public void refreshJobList(boolean isClear)
{
logger.trace("refreshing job list !!");
try
{
if (getSelectedStatusTypes() != null && !isClear && getSelectedStatusTypes().isEmpty())
{
this.setJobRows( new ArrayList<JobRow>());
facesMessages.addToControl("statusTypesId", "Please select at least one Status Type.", null);
}
else
{
if(!this.render || this.getNumberOfRows() > 0)
{
this.setJobRows( new ArrayList<JobRow>());
this.render = true;
this.loadData(0, 50, null);
}
}
}
catch (Exception e)
{
logger.error("Problem with refreshing job list. isClear=" + isClear + ", jobManager.getListOfJobs(" +
selectedStatusTypes + ", " + fileSearchName + ", " + fromDate + ", " + toDate, e);
}
}
/**
* @return the render
*/
public boolean isRender()
{
return render;
}
/**
* @param render the render to set
*/
public void setRender(boolean render)
{
this.render = render;
}
/**
* @return the numberOfRows
*/
public int getNumberOfRows()
{
return this.numberOfRows;
}
/**
* @param numberOfRows the numberOfRows to set
*/
public void setNumberOfRows(int numberOfRows)
{
this.numberOfRows = numberOfRows;
}
}
So It's working perfectly fine. It get chunks of rows via lazy loading. But the only problem is ...as I scroll through the SDT. Looks like it caches the range. So It calls loadData() multiple times. e.g. If first time it calls for range 0 to 50. Then next time it calls two times ...with range 0 to 50 and with new range 50 - 100....So as it progresses ...it keeps on calling for previous range....which will be performance degrde in long run..
Any advice why loadData() gets called multiple times ?
-
2. Re: How to load rows on demand using rich:scrollabledatatable
richdeveloper Oct 10, 2011 9:05 AM (in response to richdeveloper)Also selection deosn't work....following is the snippet with the selction.....
<rich:scrollableDataTable id="jobListId" value="#{jobScrollableDataModel}" var="jobListRow"
rendered="true" rowClasses="even-row, odd-row" rows="#{configurationManager.maximumJobsInList}" height="400px" selectionMode="single" rowKey="#{jobListRow.jobId}" rowKeyVar="rkv" ignoreDupResponses="true" style="z-index:-1;width:100%;" selection="#{jobScrollableDataModel.currentSelection}">
backend bean code:
private Selection selection;
/**
* @return the selection
*/
public Selection getCurrentSelection()
{
return selection;
}
/**
* @param selection the selection to set
*/
public void setCurrentSelection(Selection selection)
{
this.selection = selection;
}
Alert jobAlert;
public String takeSelection() {
Iterator<Object> iterator = getCurrentSelection().getKeys();
if(iterator.hasNext()){
Object key = iterator.next();
table.setRowKey(key);
if (table.isRowAvailable()) {
table.setRowKey(key);
this.setSelectJobRow((JobRow) table.getRowData());
}
}
return null;
}
-
3. Re: How to load rows on demand using rich:scrollabledatatable
richdeveloper Oct 14, 2011 11:14 AM (in response to richdeveloper)Ok. Found solution my self :
I needed following to trigger selection: before selection was always null. after supporting following event selction is correct.
<a:support event="onselectionchange" action="#{jobScrollableDataModel.takeSelection}" />