[richfaces-issues] [JBoss JIRA] Resolved: (RF-4283) Rich:datascroller does not show the correct number of pages when used with ExtendedDataModel

Nick Belaevski (JIRA) jira-events at lists.jboss.org
Mon Aug 25 15:41:39 EDT 2008


     [ https://jira.jboss.org/jira/browse/RF-4283?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Nick Belaevski resolved RF-4283.
--------------------------------

    Fix Version/s: 3.2.2
       Resolution: Out of Date
         Assignee: Tsikhon Kuprevich


This problem is not reproduced with 3.2.2.BETA5, but is reproduced with BETA2, so I resolve the issue.

One more note: set ajaxSingle="false" in datascroller in order for update() method to be called or add dataTable to process attribute of datascroller! Without that, datascroller works, but data do not get scrolled.

> Rich:datascroller does not show the correct number of pages when used with ExtendedDataModel
> --------------------------------------------------------------------------------------------
>
>                 Key: RF-4283
>                 URL: https://jira.jboss.org/jira/browse/RF-4283
>             Project: RichFaces
>          Issue Type: Bug
>    Affects Versions: 3.0.0
>            Reporter: Hristo Mitkov
>            Assignee: Tsikhon Kuprevich
>            Priority: Critical
>             Fix For: 3.2.2
>
>
> Rich:datascroller cannnot be set to show the correct number of pages when using an ExtendedDataModel. The reason for this is that ListSequenceDataModel is used for calculating the number of pages instead of ExtendedDataModel.
> I have TestDataModel class which extends SerializableDataModel where in wrappedData I return just 10 elements but my getRowCount method returns the number of all records in the database which is 500. The datascroller though shows that there is only one page.
> I debug the richfaces code to see how the datascroller is rendered.
> This is done mainly in DatascrollerTemplate and DataScrollerRenderer in package org.richfaces.renderkit.html. As expected the datascroller uses the DataModel of the DataTable to calculate the number of pages:
> org.richfaces.component.UIDatascroller.getRowCount(UIData data)
> and after:
> UIDataAdapter.getRowCount(){
> ... return getExtendedDataModel().getRowCount();
> }
> Here getExtendedDataModel() returns an instance of ModifiableModel which field "originalModel" contains my custom TestDataModel. So modifiableModel.getOriginalModel.getRowCount will return 500 as I need. But look at the implementation of modifiableModel.getRowCount:
> public int getRowCount() {
> return delegate.getRowCount();
> }
> !!!???
> delegate is an instance of ListSequenceDataModel which contains the list wrappedKeys. So getRowCount() returns wrappedKeys.size() which is 10 so the datascroller renders with only one page.
> The correct implementation of modifiableModel.getRowCount should be:
> public int getRowCount() {
> return originalModel.getRowCount();
> }
> At the time of rendering the dataTable when the model is created () both fields: modifiableModel.originalModel and modifiableModel.delegate are set to TestDataModel. But at some point delegate is set to ListSequenceDataModel and returns the size of the list.
> Another thing is that there is no way to set the number of pages directly to the UIDatascroller component either by an attribute or by the API 
> Here is an example code:
> This is the datamodel class:
> @Name("testDataModel")
> @Scope(ScopeType.SESSION)
> public class TestDataModel extends SerializableDataModel {
> 	private Integer currentPk;
> 	private boolean detached = false;
> 	private boolean descending;
> 	private List<Integer> wrappedKeys = null;
> 	private final Map<Integer, Container> wrappedData = new HashMap<Integer, Container>();
> 	private int rowCount=0;
> 	@Override
> 	public Object getRowKey() {
> 		return currentPk;
> 	}
> 	@Override
> 	public void setRowKey(Object key) {
> 		this.currentPk = (Integer) key;
> 	}
> 	@In(create = true)
> 	private ContainerService containerManager;
> 	@Override
> 	public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
> 		if (detached){
> 			for (Integer key : wrappedKeys) {
> 				setRowKey(key);
> 				visitor.process(context, key, argument);
> 			}
> 		} else {
> 			int firstRow = ((SequenceRange) range).getFirstRow();
> 			int numberOfRows = 10;// ((SequenceRange) range).getRows();
> 			wrappedKeys = new ArrayList<Integer>();
> 			for (Container container : containerManager.findContainersPaged(firstRow, numberOfRows, null, null)) {
> 				wrappedKeys.add(container.getId());
> 				wrappedData.put(container.getId(), container);
> 				visitor.process(context, container.getId(), argument);
> 			}
> 		}
> 	}
> 	@Override
> 	public SerializableDataModel getSerializableModel(Range range) {
> 		if (wrappedKeys != null) {
> 			detached = true;
> 			return this;
> 		}
> 		return null;
> 	}
> 	@Override
> 	public void update() {
> 		detached = false;
> 	}
> 	
> 	@Override
> 	public int getRowCount() {
> 			if(rowCount==0){
> 				rowCount=containerManager.countContainers();
> 			}
>              // Here for test and debug purposes you can comment the code above and just do: 
>              // return 500;
> 		return rowCount;
> 	}
> 	@Override
> 	public Object getRowData() {
> 		
> 		if (currentPk == null) {
> 			return null;
> 		} else {
> 			Container container = wrappedData.get(currentPk);
> 			if (container == null) {
> 				container = containerManager.getContainerById(currentPk);
> 				wrappedData.put(currentPk, container);
> 			}
> 			return container;
> 		}
> 	}
> 	@Override
> 	public boolean isRowAvailable() {
> 		if (currentPk == null) {
> 			return false;
> 		}
> 		if (wrappedKeys.contains(currentPk)) {
> 			return true;
> 		}
> 		if (wrappedData.entrySet().contains(currentPk)) {
> 			return true;
> 		}
> 		if (containerManager.getContainerById(currentPk) != null) {
> 			return true;
> 		}
> 		return false;
> 	}
> 	@Override
> 	public void setRowIndex(int index) {
> 	}
> 	@Override
> 	public int getRowIndex() {
> 		throw new UnsupportedOperationException();
> 	}
> 	@Override
> 	public Object getWrappedData() {
> 		throw new UnsupportedOperationException();
> 	}
> 	@Override
> 	public void setWrappedData(java.lang.Object data) {
> 		throw new UnsupportedOperationException();
> 	}
> }
> Thisis the seam managed bean. It can be any kind of jsf managed bean:
> @Stateful
> @Name("containerManager")
> public class ContainerManager  implements ContainerService {
>         public Integer countContainers() {
>               //For test and debug purposes you can comment the following code and just: return 500;
> 		Session session = (Session) entityManager.getDelegate();
> 		Criteria criteria = session.createCriteria(Container.class).setProjection(Projections.rowCount());
> 	        Integer containerCount = (Integer) criteria.uniqueResult();
> 		return containerCount;
> 	  }
> 	public List<Container> findContainersPaged(int firstRow, int numberOfRows, String sortField, boolean descending) {
> 		List<Container> container = entityManager.createQuery("select c from Container c ").setFirstResult(firstRow).setMaxResults(numberOfRows).getResultList();
> 		return container;
> 	}
> 	public Container getContainerById(Integer id) {
> 		return entityManager.find(Container.class, id);
> 	}
>  }
> This is the page
> <rich:dataTable id="containerList" rows="10"  var="c" value="#{testDataModel}">
> 					<rich:column>
> 						<f:facet name="header">
> 							<h:outputText value="Name" />
> 						</f:facet>
> 						<h:outputText value="#{c.name}"  />
> 					</rich:column>
> </rich:dataTable>
> <rich:datascroller align="left" for="containerList" maxPages="10" rendered="true" />

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the richfaces-issues mailing list