You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by John Reynolds <jo...@austin.rr.com> on 2004/10/02 00:51:20 UTC

Editable Table questions

I am trying to create an example using contrib:Table that contains an
editable column.

I have been successful to a point, the table displays a column of
TextFields as desired, and the changes that I make to these fields are
captured when I activate a Submit button on the Form.  The List of items
contains all the changes.

My problem is that the Form is not submitted when the user navigates
between pages or when the sort is changed by clicking on the column
headers.  I can fix the "sort" problem by preceding the column names
with "*", but I don't know how to get the TablePages component to submit
the Form.


My latest attempt was to try using the FormTable instead of Table.
Apparently, I am missing some key concept.  When using the
contrib.:FormTable, all the column headers and paging links do submit
the Form, but none of my changes to the TextFields are picked up in the
formSubmit(IRequestCycle). The items in the List are unchanged from when
the page was originally submitted.
 

I assume that there is some difference in "unwinding" between a standard
Table and a Form Table, but I am not sure how to proceed.  Any help will
be appreciated.

 

Here is the HTML template definition :

 

<form jwcid="@Form" listener="ognl:listeners.formSubmit">

 

<table class="mytable" jwcid="table@contrib:FormTable" width="90%"

source="ognl:dataItems"

columns="1:SSN:SSN, 2:First Name:FirstName, 3:Last Name:LastName,
=birthDateColumn, 5:Height:Height, Weight"

rowsClass="ognl:beans.evenOdd.next"

pageSize="6"    >

<span jwcid="WeightColumnValue@Block">

<span jwcid="editableWeight@TextField"
value="ognl:components.table.tableRow.Weight" size="4"/>

</span>

</table>

<input type="submit" value="Update"/>

</form>


Here's my submit method:

 

   public void formSubmit(IRequestCycle cycle)

    {

      System.out.println("The form was submitted");

            

       // Process the submitted form

        List list = getDataItems();

 

        // Do something to process the list changes

        int count = list.size();

        for (int i = 0; i < 1; i++)

        {

            DataItem item = (DataItem) list.get(i);

            System.out.println(item.getWeight());

        }

 

        // Always important to set peristent properties; otherwise
changes

        // made in this request cycle will be lost.  The framework

        // makes a copy of the list.

        setDataItems(list);

    }


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Editable Table questions

Posted by Mind Bridge <mi...@yahoo.com>.
Hi,


> My problem is that the Form is not submitted when the user navigates
> between pages or when the sort is changed by clicking on the column
> headers.  I can fix the "sort" problem by preceding the column names
> with "*", but I don't know how to get the TablePages component to submit
> the Form.

Please see the documentation of FormTable:
http://jakarta.apache.org/tapestry/doc/ComponentReference/contrib.FormTable.html

In its beginning it describes the steps it takes to make sure that the links
produced submit the form (see the differences with Table -- the three
bullets).

The "*" trick is the third one. In addition, FormTable also uses
TableFormPages rather than TablePages to make sure the page links submit the
form. And it also automatically stores the data into the form itself using
Hidden fields to ensure that you will not get a StaleLinkException if your
data changes between render and rewind (e.g. if another user adds a new
entry after you render the table, but before you submit it; if the Back
buttton has been used before, etc)

All of this can be done manually using the lower-end Table components like
TableView, TableFormPages, etc. FormTable simply collects those elements for
you automatically so that you don't have to worry about it.

>
> My latest attempt was to try using the FormTable instead of Table.
> Apparently, I am missing some key concept.  When using the
> contrib.:FormTable, all the column headers and paging links do submit
> the Form, but none of my changes to the TextFields are picked up in the
> formSubmit(IRequestCycle). The items in the List are unchanged from when
> the page was originally submitted.

This is a direct consequence of the last element of FormTable described
above. During rewind the data does not come from the 'source' binding (as
that may change between render and rewind), but is generated from what is
stored in the form. In other words, modifying those objects in the simplest
form described in the message will likely NOT affect the objects passed in
'source'.

The data is normally written to and read from the form using the standard
Tapestry mechanisms for converting the data to a String and back. This
probably means that your objects are serialized, the serialized
representation is converted to String, and then they are deserialized (into
other objects) during the rewind of the form. This may work well for what is
being done, but one may also use the 'convertor' parameter of FormTable to
pass an IPrimaryKeyConvertor object and specify how the objects should be
represented in the form. This usually avoids serialization and gives you the
freedom to choose what object to return when you are given a primary key.
For example, it may be the appropriate object in the list passed to
'source'. This will ensure that modifications occur directly on those
objects, rather than on their copies.

Another very important element that absolutely must be considered is that
most forms should NOT apply the changes to the database if the validation of
any of the input fields fails (e.g. if you enter an incorrect date). In
addition, most forms have 'Cancel' buttons. Even if they are submitted,
nothing should happen if 'Cancel' has been pressed.


Taking all of this together, here is a simple approach that I would suggest
in your case:

- Implement IPrimaryKeyConvertor (possibly just have your page implement
it), and make sure its getValue() returns objects from your stash that you
pass to 'source', rather than new ones. This means that you will modify the
objects that will be rendered and things should work as you want them.
Just be careful -- the object with that primary key may NOT exist, e.g. if
it has been deleted and the Back button has been used. In cases like that
you can just return a new empty object.


In the more general case, however, a somewhat more elaborate approach using
the form listeners will be needed to handle Cancel and validation errors
properly.




---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 9/28/2004


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org