Hi,
On Jan 21, 2008, at 7:43 AM, Jonathan Rockway wrote:
Along these lines, how is everyone doing multi-page forms? I like
to do
GET/POST/redirect, but that needs the session to get the data from
page
1 to page 2. Without a session, I use the old "POST returns the form
with hidden fields that is page 1", but i *hate* that technique. So I
use the session.
I'm going through this as well right now, doing a small checkout-
style multi-step form. The following is my current idea on how to
deal with this. Its still a rough draft but I think it will work ok.
Any feedback is appreciated.
Below, when I mention PUT, i'm using PUT-tunneled-over-POST for web
clients.
Users start by POST'ing to /checkout/start. This will create a cart
containing the items to include in this checkout. In our case, we
always include all the items currently pending payment, other sites
might have a different policy/requirements. The point of this first
step is to create a cart, with a unique identifier. We associate the
cart with the logged in user and we include a security hash based on
the cart id and user id on each form. After all this, we redirect to /
checkout/cart/UNIQUE_ID/step1.
On each step, the GET will show the appropriate form. The user will
fill the fields, and PUTs the result to the same address. Information
received is checked and valid fields are stored in the cart state.
After that, if all fields are correct, we redirect to the next step.
If they are not correct, we redirect to the same URL. Previous
values, and error messages or error codes are given back using URL
parameters. Usually we have very little parameters and they are all
limited in size, so it fits the 1k max URL size.
Aside: If a field is unusually large, we need some kind of temporary
storage, and this could break somewhat the Idempotence of each
request. We could sha1 hash the bad content, store it somewhere keyed
on this hash and send the hash to the client. This might solve it.
Fortunately I never needed this.
On each step, the process updates the fields on the cart, and at the
final step, we change the status of the cart to 'ready_to_process'
and redirect the user to a success page.
The things I like on this approach:
Every request is idempotent: you can reload to your hearts content
any page, you can post several times each step to update previous
entered information, you can go back and forward, everything.
There is no final step of copying the cart usually stored in the
session to your orders table. The cart is the order, you build the
order step by step until its ready to be processed by our back-office
staff.
Old, unfinished orders can be cleaned up after some time, and if they
are request in the future you can just create a new one and redirect
to it, or you can give the user a error message and suggest the
creation of a new one. I keep carts for one year or until the items
in it expire, but that's my business :). Yours might need different
timings. You could also erase old carts based on the step they are at.
If you start a new checkout with another one still open, there are
several options. My personal choice is to merge the old order with
the new items, but you could also create a new one and suggest
merging the old one (merging on demand). This part also depends on
your business needs.
Anyway, this is my currently thinking on this subject. Any feedback
appreciated.
(I also use the Flash for "You've added a record
successfully!" messages. Totally non-RESTful, but the users seem to
like it.)
You not redirect with parameters? something like
po_id=1&p1=Pedro&[EMAIL PROTECTED] to use message id 1 with two
parameters, 1=Pedro and [EMAIL PROTECTED]
RESTfull, no?
Best regards,
--
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: [EMAIL PROTECTED]
Use XMPP!
_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/