views:

26

answers:

2

We have the unusual requirement of a multi-step form through GET requests. So, instead of POSTing the forms, we're using GET requests to pass new parameters to the query. So, the basic idea is that there's a treatment, and a date passed to the query. A three-step form if you will.

  1. Show available treatments, pick one
  2. Show available dates (there's business logic in the background that figures these out)
  3. Pick a time

The URL will go through the following states

  1. site.com/bookings/new
  2. site.com/bookings/new/[id|name_of_treatment] (by this, I mean it could either by the ID field or the name of the the treatment)
  3. site.com/bookings/new/[id|name_of_treatment]/2010-12-12/

So, my route looks like this:

map.connect 'bookings/new/:massage_type/:date', :controller => :bookings, :action => :new

massage_type is synonymous with the treatment_id.

So my form_tag looks like this:

<% form_tag( {:action => "new"}, :method => "get" ) do %>

The problem I'm having is that I want it to just give me back the URL site.com/bookings/new/[id|name_of_treatment]/ but instead it gives back the following URL:

http://localhost:3000/bookings/new?massage_type[treatment_id]=1&amp;commit=actionnew

I don't suppose anyone knows?

A: 

By definition, the result of a GET request will have a query string (?param1=value1&param2=value2&...) in its URL. To get rid of those, you'll have to either start using POST or immediately redirect to the desired URL upon receiving a GET request.

I rather like the redirect approach because it doesn't show that confusing/annoying message about resubmitting POST data when the user refreshes their browser.

jnylen
One option I was thinking of was instant redirection, which is perfectly viable I guess
Kezzer
A: 

Forms that use GET are adding the input values as query parameters. There's no way to make the form post to a different URL, where the input values are part of the URL instead - it's just not supported by the HTML standard.

You could use URL rewrite to remap the incoming URLs of this type to the one you want, however that's not really a good solution, because this would result in a second request.

However, what I don't understand is why does the form need to do GET to that specific URL. Is it a requirement that these URLs can be constructed by the user manually, instead of using the form?

If there is no such requirement, I would advise to use standard POST form to http://localhost:3000/bookings/new and modify the form in the response based on the parameters in the POST body, as necessary.

Better yet, write some Ajax that would update the form according to the user's choice, without making a full form submit, until the user has finished all the choices.

Franci Penov
It's a three-step form basically, but you should be able to jump to any step, because another page offers the opportunity to go straight to a second step for example.
Kezzer
The other page can get you to the right state by `POST`ing the right parameters. The only reason you would need that URL format is if you want to enable the user to construct it by hand (as I mentioned it already).
Franci Penov
Well, it _would_ be possible to POST from the other pages I guess. I don't like multi-step forms at all really, but we wanted a solution that is accessible using progressive enhancement so we don't rely on javascript entirely. We basically start from the ground up. I guess I can POST it, and then from the other pages, I could create loads of forms that POST the necessary variables
Kezzer
Furthermore, I wanted the URL to reflect where you were in the process.
Kezzer
Why? What goal would this serve? :-) But sure, you can do that, however, as I said, the HTML spec is clear about how the URL is formed when sending a form (through either `GET` or `POST`). Though, you could execute Javascript on the form submit, that would redirect the browser to the URL you want using the input fields of the form.
Franci Penov