8 Replies Latest reply on Nov 5, 2007 7:44 AM by Dinesh Gupta

    dataTable and dataScroller - mismatch on ids

    Aoife Kavanagh Newbie

      Hi,

      I'm evaluating JBoss RichFaces 3.0.0 with Sun JSF RI 1.1. In particular I am looking at the dataTable and dataScroller components and I have a couple of questions.

      Firstly, is using the dataScroller component the only way to get paging in the dataTable? Or can it be achieved in any other manner?
      Secondly, while the demo works fine I can't get a simple app of my own using this combination to run. I have a dataScroller component and dataTable and every time I try to access JSP I get error

      org.apache.jasper.JasperException: could not dataTable with id 'partyList'


      Snippet from jsp is:
      <rich:datascroller for="partyList" maxPages="5" />
      <rich:spacer height="10" />
      <rich:dataTable width="483" id="partyList" rows="10"
       value="#{datatablebb.rowEntryList}" var="category">
       ...
      </dataTable>


      Do I need to set up the ID somewhere else as well?

      Thanks,
      Aoife

        • 1. Re: dataTable and dataScroller - mismatch on ids
          Ilya Shaikovsky Master

          Oh.. At firts try to use latest versions of the RF and A4J, because of many issues was solved into. And check you JSF version it musn't be earlier than 1.1.02.

          • 2. Re: dataTable and dataScroller - mismatch on ids
            Aoife Kavanagh Newbie

            Hi,

            My Sun RI is 1.1_02 which is the same version I'm using when running the demo app. I was working with RichFaces 3.0.0 but have also tried using snapshot of 3.0.1 and ajax4jsf-1.1.1 snapshot and i get the same behaviour. I'm working with JDK 1.5.0_11 and using plain JSPs, not facelets.

            I presume that I don't need to have any sort of matching id or anything in my backing beans?

            Aoife

            • 3. Re: dataTable and dataScroller - mismatch on ids
              Nick Belaevski Master

              Hello!

              Try wrapping dataScroller & dataTable into a4j:outputPanel.

              • 4. Re: dataTable and dataScroller - mismatch on ids
                Aoife Kavanagh Newbie

                Hi,

                I finally got this working but to do so I had to use Sun RI JSF 1.2_04, JSP 2.1 with May snapshots of ajax4jsf and RichFaces 3.0.1 running on Tomcat 6.
                While it's good to get it working I don't understand how the shipped demo works as expected with JSF 1.1_02 with JSP 2.0 on Tomcat 5. That combo just doesn't work with my simple app.

                Aoife

                • 5. Re: dataTable and dataScroller - mismatch on ids
                  Aoife Kavanagh Newbie

                  Oh, looks like I may have spoken to soon...
                  Page now displays without apparent error but scroller doesn't actually change the data displayed in the dataTable :-(

                  • 6. Re: dataTable and dataScroller - mismatch on ids
                    Mikael Andersson Master

                    I'm also running into problems with the dataScroller.

                    I just upgraded an old demo app of mine to use the latest libraries, and now the dataScroller doesn't reRrender the relevant bits on the page anymore.

                    I tried wrapping the table and scroller in a a4j:outputPanel, didn't work.
                    Tried with both h:form and a4j:form, no change.

                    The server side bits seems to get set, because when doing a refresh of the page it gets rendered properly.

                    Libs:
                    myfaces and tomahawk 1.1.5
                    ajax4jsf and richfaces snapshots are the latest
                    facelets 1.1.12


                    - Mike

                    • 7. Re: dataTable and dataScroller - mismatch on ids
                      Haohua xie Newbie

                      try to add ajaxRendered="true" to <a4j:outputPanel >
                      this example works well on my jboss 4.2.0 GA and richfaces 3.0.1

                      <a4j:form ajaxSubmit="true" >
                      <a4j:outputPanel ajaxRendered="true">
                       <rich:datascroller id="carList_scroller" for="carList" maxPages="20" />
                       <rich:spacer height="30" />
                       <rich:dataTable width="483" id="carList" rows="10" columnClasses="col"
                       value="#{dataTableScrollerBean.allCars}" var="category">
                       <f:facet name="header">
                       <rich:columnGroup>
                       <h:column>
                       <h:outputText styleClass="headerText" value="Make" />
                       </h:column>
                       <h:column>
                       <h:outputText styleClass="headerText" value="Model" />
                       </h:column>
                       <h:column>
                       <h:outputText styleClass="headerText" value="Price" />
                       </h:column>
                       <h:column>
                       <h:outputText styleClass="headerText" value="Mileage" />
                       </h:column>
                       </rich:columnGroup>
                       </f:facet>
                      
                       <h:column>
                       <h:outputText value="#{category.make}" />
                       </h:column>
                       <h:column>
                       <h:outputText value="#{category.model}" />
                       </h:column>
                       <h:column>
                       <h:outputText value="#{category.price}" />
                       </h:column>
                       <h:column>
                       <h:outputText value="#{category.mileage}" />
                       </h:column>
                      
                      
                      
                       </rich:dataTable>
                      
                       </a4j:outputPanel>
                      </a4j:form>
                      

                      "mail.micke@gmail.com" wrote:
                      I'm also running into problems with the dataScroller.

                      I just upgraded an old demo app of mine to use the latest libraries, and now the dataScroller doesn't reRrender the relevant bits on the page anymore.

                      I tried wrapping the table and scroller in a a4j:outputPanel, didn't work.
                      Tried with both h:form and a4j:form, no change.

                      The server side bits seems to get set, because when doing a refresh of the page it gets rendered properly.

                      Libs:
                      myfaces and tomahawk 1.1.5
                      ajax4jsf and richfaces snapshots are the latest



                      facelets 1.1.12


                      - Mike



                      • 8. Re: dataTable and dataScroller - mismatch on ids
                        Dinesh Gupta Newbie

                        Hi,

                        If I am using DataModel for datatable its giving aception
                        My extendedDataModel.jsp code is here

                        <f:view>
                         <h:outputText value="Dinesh #{AuctionDataModel}"/>
                         <h:form>
                         <a4j:outputPanel ajaxRendered="true">
                         <rich:datascroller for="auction" maxPages="5" />
                         <rich:spacer height="30" />
                         <rich:dataTable id="auction" value="#{AuctionDataModel}"
                         columnClasses="col1,col2,col3,col4," var="item" rows="10"
                         width="100%">
                         <rich:column>
                         <f:facet name="header">
                         <h:outputText value="Description" />
                         </f:facet>
                         <h:outputText value="#{item.description}" />
                         </rich:column>
                         <rich:column>
                         <f:facet name="header">
                         <h:outputText value="Highest Bid" />
                         </f:facet>
                         <h:outputText id="highestBid" value="#{item.highestBid}">
                         <f:convertNumber pattern="$#,##0.00" />
                         </h:outputText>
                         </rich:column>
                         <rich:column>
                         <f:facet name="header">
                         <h:outputText value="Your Bid" />
                         </f:facet>
                        
                         <rich:message for="bid" />
                         <br />
                         <h:inputText id="bid" value="#{item.bid}">
                         <f:convertNumber />
                         <f:validateLongRange minimum="0" maximum="1000000" />
                         </h:inputText>
                         <a4j:commandLink id="bid_link" actionListener="#{item.placeBid}"
                         value="Place a bid!" reRender="bid,amount,highestBid" />
                        
                         </rich:column>
                         <rich:column>
                         <f:facet name="header">
                         <h:outputText value="Amount" />
                         </f:facet>
                         <h:outputText id="amount" value="#{item.amount}">
                         <f:convertNumber pattern="$#,##0.00" />
                         </h:outputText>
                         </rich:column>
                         </rich:dataTable>
                         </a4j:outputPanel>
                         </h:form>
                        </f:view>
                        


                        And Datamodel backing bean is
                        package dataScroller;
                        
                        import java.io.IOException;
                        import java.util.ArrayList;
                        import java.util.HashMap;
                        import java.util.List;
                        import java.util.Map;
                        
                        import javax.faces.context.FacesContext;
                        
                        import org.ajax4jsf.model.DataVisitor;
                        import org.ajax4jsf.model.Range;
                        import org.ajax4jsf.model.SequenceRange;
                        import org.ajax4jsf.model.SerializableDataModel;
                        /**
                         *
                         * @author ias
                         * This is example class that intended to demonstrate use of ExtendedDataModel and SerializableDataModel.
                         * This implementation intended to be used as a request scope bean. However, it actually provides serialized
                         * state, so on a post-back we do not load data from the data provider. Instead we use data that was used
                         * during rendering.
                         * This data model must be used together with Data Provider, which is responsible for actual data load
                         * from the database using specific filtering and sorting. Normally Data Provider must be in either session, or conversation
                         * scope.
                         */
                        public class AuctionDataModel extends SerializableDataModel {
                        
                         private AuctionDataProvider dataProvider;
                         private Integer currentPk;
                         private Map<Integer,AuctionItem> wrappedData = new HashMap<Integer,AuctionItem>();
                         private List<Integer> wrappedKeys = null;
                         private boolean detached = false;
                        
                         /**
                         *
                         */
                         private static final long serialVersionUID = -1956179896877538628L;
                        
                         /**
                         * This method never called from framework.
                         * (non-Javadoc)
                         * @see org.ajax4jsf.model.ExtendedDataModel#getRowKey()
                         */
                         @Override
                         public Object getRowKey() {
                         return currentPk;
                         }
                         /**
                         * This method normally called by Visitor before request Data Row.
                         */
                         @Override
                         public void setRowKey(Object key) {
                         this.currentPk = (Integer) key;
                        
                         }
                         /**
                         * This is main part of Visitor pattern. Method called by framework many times during request processing.
                         */
                         @Override
                         public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
                         int firstRow = ((SequenceRange)range).getFirstRow();
                         int numberOfRows = ((SequenceRange)range).getRows();
                         if (detached) { // Is this serialized model
                        // Here we just ignore current Rage and use whatever data was saved in serialized model.
                        // Such approach uses much more getByPk() operations, instead of just one request by range.
                        // Concrete case may be different from that, so you can just load data from data provider by range.
                        // We are using wrappedKeys list only to preserve actual order of items.
                         for (Integer key:wrappedKeys) {
                         setRowKey(key);
                         visitor.process(context, key, argument);
                         }
                         } else { // if not serialized, than we request data from data provider
                         wrappedKeys = new ArrayList<Integer>();
                         for (AuctionItem item:dataProvider.getItemsByrange(new Integer(firstRow), numberOfRows, null, true)) {
                         wrappedKeys.add(item.getPk());
                         wrappedData.put(item.getPk(), item);
                         visitor.process(context, item.getPk(), argument);
                         }
                         }
                         }
                         /**
                         * This method must return actual data rows count from the Data Provider. It is used by pagination control
                         * to determine total number of data items.
                         */
                         private Integer rowCount; // better to buffer row count locally
                         @Override
                         public int getRowCount() {
                         if (rowCount==null) {
                         rowCount = new Integer(getDataProvider().getRowCount());
                         return rowCount.intValue();
                         } else {
                         return rowCount.intValue();
                         }
                         }
                         /**
                         * This is main way to obtain data row. It is intensively used by framework.
                         * We strongly recommend use of local cache in that method.
                         */
                         @Override
                         public Object getRowData() {
                         if (currentPk==null) {
                         return null;
                         } else {
                         AuctionItem ret = wrappedData.get(currentPk);
                         if (ret==null) {
                         ret = getDataProvider().getAuctionItemByPk(currentPk);
                         wrappedData.put(currentPk, ret);
                         return ret;
                         } else {
                         return ret;
                         }
                         }
                         }
                        
                         /**
                         * Unused rudiment from old JSF staff.
                         */
                         @Override
                         public int getRowIndex() {
                         throw new UnsupportedOperationException();
                         }
                        
                         /**
                         * Unused rudiment from old JSF staff.
                         */
                         @Override
                         public Object getWrappedData() {
                         throw new UnsupportedOperationException();
                         }
                        
                         /**
                         * Never called by framework.
                         */
                         @Override
                         public boolean isRowAvailable() {
                         if (currentPk==null) {
                         return false;
                         } else {
                         return getDataProvider().hasAuctionItemByPk(currentPk);
                         }
                         }
                        
                         /**
                         * Unused rudiment from old JSF staff.
                         */
                         @Override
                         public void setRowIndex(int rowIndex) {
                         throw new UnsupportedOperationException();
                         }
                        
                         /**
                         * Unused rudiment from old JSF staff.
                         */
                         @Override
                         public void setWrappedData(Object data) {
                         throw new UnsupportedOperationException();
                         }
                        
                         /**
                         * This method suppose to produce SerializableDataModel that will be serialized into View State and used on a post-back.
                         * In current implementation we just mark current model as serialized. In more complicated cases we may need to
                         * transform data to actually serialized form.
                         */
                         public SerializableDataModel getSerializableModel(Range range) {
                         if (wrappedKeys!=null) {
                         detached = true;
                        // Some activity to detach persistent data from wrappedData map may be taken here.
                        // In that specific case we are doing nothing.
                         return this;
                         } else {
                         return null;
                         }
                         }
                         /**
                         * This is helper method that is called by framework after model update. In must delegate actual database update to
                         * Data Provider.
                         */
                         @Override
                         public void update() {
                         getDataProvider().update();
                         }
                        
                         public AuctionDataProvider getDataProvider() {
                         return dataProvider;
                         }
                        
                         public void setDataProvider(AuctionDataProvider dataProvider) {
                         this.dataProvider = dataProvider;
                         }
                        
                        }
                        
                        
                        



                        i am gettin flowwing exception

                        2007-11-05 17:31:15,343 ERROR [[jsp]] (http-0.0.0.0-8080-1:) Servlet.service() for servlet jsp threw exception
                        java.lang.UnsupportedOperationException
                        at dataScroller.AuctionDataModel.getRowIndex(AuctionDataModel.java:120)
                        at org.ajax4jsf.component.UIDataAdaptor.getRowIndex(UIDataAdaptor.java:286)
                        at javax.faces.component._ComponentUtils.idsAreEqual(_ComponentUtils.java:106)
                        at javax.faces.component._ComponentUtils.findComponent(_ComponentUtils.java:75)
                        at javax.faces.component.UIComponentBase.findComponent(UIComponentBase.java:248)
                        at javax.faces.webapp.UIComponentTag.findComponent(UIComponentTag.java:425)
                        at javax.faces.webapp.UIComponentTag.doStartTag(UIComponentTag.java:256)
                        at org.apache.jsp.a4j.extendedDataModel_jsp._jspx_meth_rich_column_0(org.apache.jsp.a4j.extendedDataModel_jsp:336)
                        at org.apache.jsp.a4j.extendedDataModel_jsp._jspx_meth_rich_dataTable_0(org.apache.jsp.a4j.extendedDataModel_jsp:305)
                        at org.apache.jsp.a4j.extendedDataModel_jsp._jspx_meth_a4j_outputPanel_0(org.apache.jsp.a4j.extendedDataModel_jsp:243)
                        at org.apache.jsp.a4j.extendedDataModel_jsp._jspx_meth_h_form_0(org.apache.jsp.a4j.extendedDataModel_jsp:210)
                        at org.apache.jsp.a4j.extendedDataModel_jsp._jspx_meth_f_view_0(org.apache.jsp.a4j.extendedDataModel_jsp:165)
                        at org.apache.jsp.a4j.extendedDataModel_jsp._jspService(org.apache.jsp.a4j.extendedDataModel_jsp:125)
                        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)