[ 
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

        
_______________________________________________
richfaces-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/richfaces-issues

Reply via email to