10 Replies Latest reply on Jul 6, 2010 8:01 AM by wojciech_kochman

    Richfaces + Spring + DataTable - DataScroller Problem

    wojciech_kochman

      I try to use Richfaces DataTable with DataTableModel to have server side paging and sorting.

      My tebaleModel is a spring bean with scope "request" and " proxyMode = ScopedProxyMode.TARGET_CLASS".

      On the page is a keepAlive tag for tebaleModel bean.

      When I click next the bean is initialized but it should be restored.

      Can anybody help. I can provide the code if my question is not clear.

        • 1. Re: Richfaces + Spring + DataTable - DataScroller Problem
          nbelaevski

          Hi Wojciech,

           

          Yes, can you please post some mode code? 

          • 2. Re: Richfaces + Spring + DataTable - DataScroller Problem
            wojciech_kochman

            Hi Nick,

             

            I solved the problem, but I have another one.

             

            I went through your examle with HibernateTableModel.

             

            I've done something similar and I want to combine it with EditableTable - buttons to delete and edit rows.

            The problem is when I put in to the colum a <a4j:button> and in the button <f:setPropertyActionListener>.

            The value in the  <f:setPropertyActionListener> is not set.

             

            Please Help. Thx.

            • 3. Re: Richfaces + Spring + DataTable - DataScroller Problem
              nbelaevski

              It should be working. How does page code look like?

              • 4. Re: Richfaces + Spring + DataTable - DataScroller Problem
                wojciech_kochman

                Hi, Below is the code of the page.

                 

                <

                ui:composition xmlns="http://www.w3.org/1999/xhtml"

                 

                xmlns:h="http://java.sun.com/jsf/html"

                 

                xmlns:f="http://java.sun.com/jsf/core"

                 

                xmlns:ui="http://java.sun.com/jsf/facelets"

                 

                xmlns:rich="http://richfaces.org/rich"

                 

                xmlns:a4j="http://richfaces.org/a4j"

                 

                xmlns:bo="http://www.jataka.com/jsf"

                 

                xmlns:sii="http://x/web/jsf"

                 

                template="/templates/mainTemplate.xhtml">

                 

                <ui:define name="mainPage">

                 

                <h:form >

                 

                <a4j:outputPanel ajaxRendered="true">

                 

                <sii:userDetails id="userDetails" />

                 

                </a4j:outputPanel>

                 

                <sii:userTable />

                 

                </h:form>

                 

                <sii:confirmPanel

                 

                headerText="#{userMsg.confirmDialogHeaderText_delete}"

                 

                bean="#{userTableDataModel}" />

                 

                </ui:define>

                </

                ui:composition>

                 

                HERE is the code of sii:userTable. Action in a4j:commandButton is not run and the nested setPropertyActionListener also.

                <

                ui:component xmlns="http://www.w3.org/1999/xhtml"

                 

                xmlns:ui="http://java.sun.com/jsf/facelets"

                 

                xmlns:h="http://java.sun.com/jsf/html"

                 

                xmlns:f="http://java.sun.com/jsf/core"

                 

                xmlns:a4j="http://richfaces.org/a4j"

                 

                xmlns:rich="http://richfaces.org/rich"

                 

                xmlns:sii="http://x/web/jsf">

                 

                <ui:param name="bean" value="#{userTableDataModel}" />

                 

                <a4j:keepAlive beanName="userTableDataModel" />

                 

                <a4j:region>

                 

                <rich:dataTable id="table" value="#{bean.model}" var="user"

                 

                width="580px" rows="#{bean.pageSize}" sortMode="single"

                 

                selectionMode="single" >

                 

                <f:facet name="header">

                 

                <h:panelGroup>

                 

                <h:graphicImage value="/images/icons/onebit/onebit_17.png"

                 

                width="30" />

                 

                <h:outputText value="#{userMsg.users}" />

                 

                </h:panelGroup>

                 

                 

                </f:facet>

                 

                <rich:column sortable="true" label="#{userMsg.firstName}"

                 

                sortBy="#{user.firstName}">

                 

                <f:facet name="header">

                 

                <h:outputText value="#{userMsg.firstName}" />

                 

                </f:facet>

                 

                <h:outputText value="#{user.firstName}" />

                 

                </rich:column>

                 

                <rich:column label="#{userMsg.lastName}" sortable="true"

                 

                sortBy="#{user.lastName}">

                 

                <f:facet name="header">

                 

                <h:outputText value="#{userMsg.lastName}" />

                 

                </f:facet>

                 

                <h:outputText value="#{user.lastName}" />

                 

                </rich:column>

                 

                <rich:column sortable="true" sortBy="#{user.login}"

                 

                label="#{userMsg.login}">

                 

                <f:facet name="header">

                 

                <h:outputText value="#{userMsg.login}" />

                 

                </f:facet>

                 

                <h:outputText value="#{user.login}" />

                 

                </rich:column>

                 

                <rich:column>

                 

                <f:facet name="header">

                Show

                 

                </f:facet>

                 

                <a4j:commandButton value="Show" action="#{bean.show}" >

                 

                <f:setPropertyActionListener value="#{user}"

                 

                target="#{bean.model.currentUser}" />

                 

                </a4j:commandButton>

                 

                </rich:column>

                 

                <rich:column>

                 

                <f:facet name="header">

                 

                <h:outputText value="#{userMsg.actions}" />

                 

                </f:facet>

                 

                <sii:tableDeleteButton value="#{user}"

                 

                valueToSet="#{bean.currentUser}"

                 

                toolTipText="#{userMsg.delete}" />

                 

                </rich:column>

                 

                <f:facet name="footer">

                 

                <sii:dataScroller pageNo="#{bean.pageNo}" pages="#{bean.pages}"

                 

                pagesList="#{bean.pagesList}" />

                 

                </f:facet>

                 

                </rich:dataTable>

                 

                </a4j:region>

                </

                ui:component>

                • 5. Re: Richfaces + Spring + DataTable - DataScroller Problem
                  wojciech_kochman

                  Here is the code of beans:

                   

                  @Component
                  @Scope
                  ("request")
                  public
                  
                   
                   class UserTableDataModel extends BaseTableDataModel<User> {
                   
                  @Autowired
                   
                  private UserManager userManager;
                   
                  private User currentUser;
                   
                  public UserTableDataModel() {
                   
                  super(User.class);
                  }
                   
                   
                  @PostConstruct
                   
                  public void init() {
                   
                  itemCount = getRowCount();
                   
                  super.init();
                  }
                   
                   
                  public String delete() {
                   
                  if (currentUser != null) {
                   
                  userManager.deleteUser(currentUser.getId());
                  }
                   
                  cachedItems = null;
                   
                  cachedRange = null;
                   
                  return null;
                  }
                   
                  @Override
                   
                  public void walk(FacesContext facesContext, DataVisitor visitor, Range range, Object argument) throws IOException {
                   
                  SequenceRange sequenceRange = (SequenceRange) range;
                   
                  if (this.cachedItems == null || !areEqualRanges(this.cachedRange, sequenceRange)) {
                   
                  int pageNumber = 0;
                   
                  int rows = 0;
                   
                  if (sequenceRange != null) {
                   
                  int first = sequenceRange.getFirstRow();
                  rows = sequenceRange.getRows();
                  pageNumber = first / rows;
                  }
                   
                  this.cachedRange = sequenceRange;
                   
                  this.cachedItems = userManager.getUsers(new PresentationInfo(new PageInfo(rows, pageNumber), createSortInfo(sortFields)));
                  }
                   
                  for (User item : this.cachedItems) {
                  visitor.process(facesContext, item, argument);
                  }
                  }
                   
                  public String show() {
                  FacesUtils.getRequest().setAttribute(
                  "recordId", currentUser.getId());
                   
                  return null;
                  }
                   
                   
                  @Override
                   
                  public int getRowCount() {
                   
                  return userManager.getUserCount();
                  }
                   
                   
                  /**
                  * Getter for currentUser.
                  *
                  @return the currentUser
                  */
                  
                   
                  public User getCurrentUser() {
                   
                  return currentUser;
                  }
                   
                   
                  /**
                  * Setter for currentUser.
                  *
                  @param currentUser the currentUser to set
                  */
                  
                   
                  public void setCurrentUser(User currentUser) {
                   
                  this.currentUser = currentUser;
                  }
                   
                  }
                  
                  public
                  
                   abstract class BaseTableDataModel<T> extends ExtendedDataModel implements Modifiable, IBaseTableModel<T> {
                  
                  
                  public BaseTableDataModel(Class<T> entityClass) {
                  
                  
                  super();
                  
                  
                  this.entityClass = entityClass;
                      }
                  
                  
                  
                  /**
                       * 
                       */
                  
                  
                  private static final long serialVersionUID = -4188575485838003516L;
                  
                  
                  private Class<T> entityClass;
                  
                  
                  private int pageSize;
                  
                  
                  private int pageNo;
                  
                  
                  private int pages;
                  
                  
                  protected int itemCount;
                  
                  
                  private List<SelectItem> pagesList;
                      List<SortField2> 
                  
                  sortFields;
                      List<FilterField> 
                  
                  filterFields;
                  
                  
                  
                  private T dataItem;
                  
                  
                  
                  protected SequenceRange cachedRange;
                  
                  
                  
                  protected List<T> cachedItems;
                  
                  
                  
                  public void init() {
                  
                  
                  pageSize = 2;
                  
                  
                  pageNo = 1;
                  
                  
                  if (itemCount % pageSize > 0) {
                  
                  
                  pages = (itemCount / pageSize) + 1;
                          } 
                  
                  else {
                  
                  
                  pages = itemCount / pageSize;
                          }
                  
                  
                  pagesList = new ArrayList<SelectItem>();
                  
                  
                  for (int i = 1; i < pages + 1; i++) {
                  
                  
                  pagesList.add(new SelectItem(i));
                          }
                      }
                  
                  
                  
                  /**
                       * Getter for pagesList.
                       * 
                       * 
                  
                  
                  @return the pagesList
                       */
                  
                  
                  public List<SelectItem> getPagesList() {
                  
                  
                  return pagesList;
                      }
                  
                  
                  
                  protected boolean areEqualRanges(SequenceRange range1, SequenceRange range2) {
                  
                  
                  if (range1 == null || range2 == null) {
                  
                  
                  return range1 == null && range2 == null;
                          } 
                  
                  else {
                  
                  
                  return range1.getFirstRow() == range2.getFirstRow() && range1.getRows() == range2.getRows();
                          }
                      }
                  
                  
                  
                  /**
                       * Getter for pageSize.
                       * 
                       * 
                  
                  
                  @return the pageSize
                       */
                  
                  
                  public int getPageSize() {
                  
                  
                  return pageSize;
                      }
                  
                  
                  
                  /**
                       * Setter for pageSize.
                       * 
                       * 
                  
                  
                  @param pageSize the pageSize to set
                       */
                  
                  
                  public void setPageSize(int pageSize) {
                  
                  
                  this.pageSize = pageSize;
                      }
                  
                  
                  
                  /**
                       * Getter for pageNo.
                       * 
                       * 
                  
                  
                  @return the pageNo
                       */
                  
                  
                  public int getPageNo() {
                  
                  
                  return pageNo;
                      }
                  
                  
                  
                  /**
                       * Setter for pageNo.
                       * 
                       * 
                  
                  
                  @param pageNo the pageNo to set
                       */
                  
                  
                  public void setPageNo(int pageNo) {
                  
                  
                  this.pageNo = pageNo;
                      }
                  
                  
                  
                  /**
                       * Getter for pages.
                       * 
                       * 
                  
                  
                  @return the pages
                       */
                  
                  
                  public int getPages() {
                  
                  
                  return pages;
                      }
                  
                  
                  
                  @Override
                  
                  
                  public void modify(List<FilterField> filterFields, List<SortField2> sortFields) {
                  
                  
                  this.sortFields = sortFields;
                  
                  
                  this.filterFields = filterFields;
                  
                  
                  cachedItems = null;
                      }
                  
                  
                  
                  protected SortInfo createSortInfo(List<SortField2> sortFields) {
                          SortInfo sortInfo = 
                  
                  null;
                  
                  
                  if (sortFields != null && !sortFields.isEmpty()) {
                              sortInfo = 
                  
                  new SortInfo();
                  
                  
                  for (SortField2 sf : sortFields) {
                                  Ordering order = sf.getOrdering();
                                  String exp = sf.getExpression().getExpressionString();
                                  String fieldName = exp.substring(exp.indexOf(
                  
                  '.') + 1, exp.indexOf('}'));
                  
                  
                  if (Ordering.ASCENDING.equals(order)) {
                                      sortInfo.addSortFieldAscending(fieldName);
                                  } 
                  
                  else {
                                      sortInfo.addSortFieldDescending(fieldName);
                                  }
                              }
                          }
                  
                  
                  return sortInfo;
                  
                      }
                  
                  
                  
                  private String getPropertyName(Expression expression) {
                          FacesContext facesContext = FacesContext.getCurrentInstance();
                  
                  
                  try {
                  
                  
                  return (String) ((ValueExpression) expression).getValue(facesContext.getELContext());
                          } 
                  
                  catch (ELException e) {
                  
                  
                  throw new FacesException(e.getMessage(), e);
                          }
                      }
                  
                  
                  
                  @Override
                  
                  
                  public Object getRowKey() {
                  
                  
                  return dataItem;
                      }
                  
                  
                  
                  @Override
                  
                  
                  public void setRowKey(Object key) {
                  
                  
                  this.dataItem = entityClass.cast(key);
                      }
                  
                  
                  
                  @Override
                  
                  
                  public Object getRowData() {
                  
                  
                  return this.dataItem;
                      }
                  
                  
                  
                  @Override
                  
                  
                  public int getRowIndex() {
                  
                  
                  return -1;
                      }
                  
                  
                  
                  @Override
                  
                  
                  public Object getWrappedData() {
                  
                  
                  return null;
                      }
                  
                  
                  
                  @Override
                  
                  
                  public boolean isRowAvailable() {
                  
                  
                  return (this.dataItem != null);
                      }
                  
                  
                  
                  @Override
                  
                  
                  public void setRowIndex(int rowIndex) {
                      }
                  
                  
                  
                  @Override
                  
                  
                  public void setWrappedData(Object data) {
                      }
                  
                  
                  
                  @Override
                  
                  
                  public ExtendedDataModel getModel() {
                  
                  
                  return this;
                      }
                  }
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  • 6. Re: Richfaces + Spring + DataTable - DataScroller Problem
                    wojciech_kochman

                    Nick,

                     

                    I found that the problem.

                    To every column id of the dataTable was added a string produced by toStrong() method of the domain object displayed in the list.

                    I made a workaround and change to string method but it's pure slution.

                     

                    Why to the id is added this String? Is it some way to change the behaviour?

                     

                    Thanks in advance.

                    • 7. Re: Richfaces + Spring + DataTable - DataScroller Problem
                      nbelaevski

                      This is happening because you are using item as row key (that's in walk(...) method). Livedemo code uses the same approach, but there Seam entity converter is used, that does actual conversion between entity and its identifier. Either declare converter via "rowKeyConverter" attribute or change your model so that ID of entity is used as row key. 

                      1 of 1 people found this helpful
                      • 8. Re: Richfaces + Spring + DataTable - DataScroller Problem
                        wojciech_kochman

                        Thanks Nick.

                        The rowKeyConverter should convert the entity to some string and vice versa?

                        I would like to make generic model for many types of object. In that case I will have to make a converter for every type, am I correct?

                         

                        Can you provide some expamle of such converter?

                         

                        I wanted to use seam EntityConvertet but seam 2 doesn't work with hibernate validator 4 which I use.

                        • 9. Re: Richfaces + Spring + DataTable - DataScroller Problem
                          nbelaevski

                          The rowKeyConverter should convert the entity to some string and vice versa?

                          Yes.

                          I would like to make generic model for many types of object. In that case I will have to make a converter for every type, am I correct?

                          That depends on implementation. You can convert entities to EntityName:EntityId string, so that your converter will need only entities session to handle conversion. Seam stores entities in conversation-scoped map using generated incremental IDs. Another possible option - don't use converter and implement necessary handling in model.

                          Can you provide some expamle of such converter?

                          Sorry, but no ready example. I'll create one if you really need it (it shouldn't be hard to implement it) and I get some time.

                          1 of 1 people found this helpful
                          • 10. Re: Richfaces + Spring + DataTable - DataScroller Problem
                            wojciech_kochman

                            Thanks Nick. It helped me. I can go forward.