Thankyou very much, this:

<binding name="keyExpression" value="literal: id"/>

did the trick nicely.

I do not know whether you are aware of a bug? in sorting columns. When I press the column link to sort I get an org.apache.hivemind.ApplicationRuntimeException, with:

Either the tableModel parameter or both source and columns parameters must be specified by component EditPrices/priceCalcTable.tableView

followed by Stack Trace:

# org.apache.tapestry.contrib.table.components.TableView.getTableModel(TableView.java:220) # org.apache.tapestry.contrib.table.components.inserted.SimpleTableColumnComponent.columnSelected(SimpleTableColumnComponent.java:149)
# sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
# sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) # sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
# java.lang.reflect.Method.invoke(Method.java:324)
# org.apache.tapestry.listener.ListenerMethodInvokerImpl.invokeTargetMethod(ListenerMethodInvokerImpl.java:214) # org.apache.tapestry.listener.ListenerMethodInvokerImpl.invokeListenerMethod(ListenerMethodInvokerImpl.java:155) # org.apache.tapestry.listener.ListenerMethodInvokerImpl.searchAndInvoke(ListenerMethodInvokerImpl.java:124) # org.apache.tapestry.listener.ListenerMethodInvokerImpl.invokeListenerMethod(ListenerMethodInvokerImpl.java:77) # org.apache.tapestry.listener.SyntheticListener.actionTriggered(SyntheticListener.java:51) # org.apache.tapestry.listener.ListenerInvokerTerminator.invokeListener(ListenerInvokerTerminator.java:51) # $ListenerInvoker_105ecb1b95c.invokeListener($ListenerInvoker_105ecb1b95c.java)
# org.apache.tapestry.link.DirectLink.trigger(DirectLink.java:105)
# org.apache.tapestry.engine.DirectService.service(DirectService.java:132)
# $IEngineService_105ecb1b9b5.service($IEngineService_105ecb1b9b5.java)
# org.apache.tapestry.services.impl.EngineServiceOuterProxy.service(EngineServiceOuterProxy.java:65)
# org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java:254)
# org.apache.tapestry.services.impl.InvokeEngineTerminator.service(InvokeEngineTerminator.java:60) # $WebRequestServicer_105ecb1b992.service($WebRequestServicer_105ecb1b992.java) # org.apache.tapestry.services.impl.DisableCachingFilter.service(DisableCachingFilter.java:48) # $WebRequestServicerFilter_105ecb1b994.service($WebRequestServicerFilter_105ecb1b994.java) # $WebRequestServicer_105ecb1b996.service($WebRequestServicer_105ecb1b996.java) # $WebRequestServicer_105ecb1b98e.service($WebRequestServicer_105ecb1b98e.java) # org.apache.tapestry.services.impl.WebRequestServicerPipelineBridge.service(WebRequestServicerPipelineBridge.java:56) # $ServletRequestServicer_105ecb1b972.service($ServletRequestServicer_105ecb1b972.java) # org.apache.tapestry.request.DecodedRequestInjector.service(DecodedRequestInjector.java:55) # $ServletRequestServicerFilter_105ecb1b96e.service($ServletRequestServicerFilter_105ecb1b96e.java) # $ServletRequestServicer_105ecb1b974.service($ServletRequestServicer_105ecb1b974.java) # org.apache.tapestry.multipart.MultipartDecoderFilter.service(MultipartDecoderFilter.java:52) # $ServletRequestServicerFilter_105ecb1b96c.service($ServletRequestServicerFilter_105ecb1b96c.java) # $ServletRequestServicer_105ecb1b974.service($ServletRequestServicer_105ecb1b974.java) # org.apache.tapestry.services.impl.SetupRequestEncoding.service(SetupRequestEncoding.java:53) # $ServletRequestServicerFilter_105ecb1b970.service($ServletRequestServicerFilter_105ecb1b970.java) # $ServletRequestServicer_105ecb1b974.service($ServletRequestServicer_105ecb1b974.java) # $ServletRequestServicer_105ecb1b966.service($ServletRequestServicer_105ecb1b966.java) # org.apache.tapestry.ApplicationServlet.doService(ApplicationServlet.java:145)
# org.apache.tapestry.ApplicationServlet.doGet(ApplicationServlet.java:101)
# javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
# javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
# org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284) # org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204) # net.sf.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:292) # net.sf.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:305) # net.sf.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) # net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:226) # net.sf.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303) # net.sf.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:173) # net.sf.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:125) # org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:233) # org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204) # org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:257) # org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) # org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) # org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245) # org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199) # org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) # org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) # org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:184) # org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) # org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164) # org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149) # org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) # org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156) # org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) # org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567)
# org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)
# org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:206)
# org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:833)
# org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:732)
# org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:619)
# org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:688)
# java.lang.Thread.run(Thread.java:552)

As seen below the source and columns parameters are specified, I assume this is due to the major changes you are currently making.

Thanks again,

Paul


Mind Bridge wrote:

Hi,

I believe the reason is that the priceCalcData values get serialized into the form, and when they get deserialized upon submit, the deserialized items are different physical objects.

Here is a simple solution: If your priceCalcData have a property that is a primary key, say 'id', you could add the following parameter to Table:

<binding name="keyExpression" value="literal: id"/>

That says that the OGNL expression 'id' will extract the primary key of the objects in 'source'.
You will kill two birds with one stone that way:
- the objects will not be serialized -- only their IDs will be stored as Hidden fields and that would make the HTML much nicer - Upon rewind (when the form is submitted) the component will try to match the keys in the Hidden fields with the keys of the objects in 'source'. The object with a matching primary key is then used. As a result, no new physical object is created as with serialization, and modifications apply to the original object (the one in 'source')

Try this -- it may help.


An alternative to the above is also to make the Table volatile:

<binding name="volatile" value="true"/>

That prevent the table from making Hidden fields (behaves like the Table from 3.x), but that will likely cause a problem if 'source' changes between requests (e.g. external database mods, mutiple browser windows, etc). So this method is usually not appropriate.

Hope this is of use,
-mb

seloha . wrote:

I am using the new contrib:Table since I believe contrib:FormTable is to de deprecated.

I think I have a very stupid mistake somewhere. I am trying to update some fields, when I get the list of table data objects they still have the old information prior to submission. If I put an invalid entry the form fails validation an has the new data redisplayed with an error message, this indicates something is working!

I am using beta-5 which was checked-out from the cvs about a week ago.

Some of the code:

.page:

<property name="priceCalcData"/>

<component id="priceCalcTable" type="contrib:Table">
  <binding name="source" value="ognl:priceCalcData"/>
  <binding name="convertor" value="ognl:priceCalcDataItemConvertor"/>
  <binding name="columns"
      value="literal:
          airport,
          areaPostcode,
          noOfPeople,
          !price,
          !exclusivePrice,
          !onewayPrice,
          !onewayExclusivePrice"/>
<binding name="rowsClass" value="ognl:'priceCalcRowbgcolor' + beans.evenOdd.next"/>
  <binding name="pageSize" value="literal:20"/>
  <binding name="row" value="ognl:rowObj"/>
  <binding name="persist" value="literal:session"/>
</component>

example of one of the columns to update:

<component id="priceColumnValue" type="Block"/>
<component id="editablePrice" type="TextField">
  <binding name="displayName" value="literal:Price"/>
<binding name="value" value="ognl:components.priceCalcTable.tableRow.price"/>
  <binding name="translator" value="translator:number,pattern=#.##"/>
  <binding name="validators" value="validators:required,min=0"/>
  <binding name="id" value="ognl:'price' + rowId"/>
</component>

template:

        <table class="priceCalcTable" jwcid="priceCalcTable">
          <tr jwcid="airportColumnValue">
            <td jwcid="displayAirport" class="priceCalcRowColor"/>
          </tr>
          <tr jwcid="areaPostcodeColumnValue">
            <td jwcid="displayAreaPostcode"/>
          </tr>
          <tr jwcid="noOfPeopleColumnValue">
            <td jwcid="displayNoOfPeople" class="priceCalcRowColor"/>
          </tr>
          <tr jwcid="priceColumnValue">
<td jwcid="editablePrice" class="priceCalcRowColor" align="right" size="8"/>
          </tr>
          <tr jwcid="exclusivePriceColumnValue">
<td jwcid="editableExclusivePrice" class="priceCalcRowColor" align="right" size="8"/>
          </tr>
          <tr jwcid="onewayPriceColumnValue">
<td jwcid="editableOnewayPrice" class="priceCalcRowColor" align="right" size="8"/>
          </tr>
          <tr jwcid="onewayExclusivePriceColumnValue">
<td jwcid="editableOnewayExclusivePrice" class="priceCalcRowColor" align="right" size="8"/>
          </tr>
        </table>

java in the form listener:

              if (validationDelegate.getHasErrors()) {
                  return;
              }

              List priceCalcData = getPriceCalcData();

this last line retrieves the original values prior to submission.

I probably haven't provided enough code or detail but maybe someone could point me in the right direction. It almost works (funny), method getPriceCalcData() is declared as:

  public abstract List getPriceCalcData();

As previously stated the validation returns the page with the entered incorrect value. It is almost like I am reading the value at the wrong time, but there is only one listener on the form?

Any help appreciated,

Paul



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to