How can I preserve the unsubmitted contents of a web form whilst calling a refresh on its structure?
August 24, 2005 5:47 AM   RSS feed for this thread Subscribe

Half way through a form, a user decides that they'd like to add a category to a selection list. How can I facilitate this without also losing everything they've typed into the form so far?

Say I have a selection list, featuring "red", "green", "blue". I have a link which takes the user to an add-a-colour page, where they add "yellow". Now, going Back preserves all the information they'd typed in before they got as far as the selection box, but doesn't update the selection box itself. Refreshing the original page updates the selection box but loses everything they've typed in so far.

I could POST the stuff filled in so far to the add-a-colour page if I used a submit button as a link - but that would mean a form with 2 submit buttons.

Selection box and page are PHP/MySQL constructions. I suspect I could do something with JavaScript events, but I'm not quite sure how. Any pointers or suggestions welcome...
posted by handee to computers & internet (17 comments total)
Your link could be a javascript hook to POST the form with a variable that tells your script "just store what's entered so far, but don't take it as the final submission". Then, when they re-enter the page, the page is pre-filled with all the selections that they've made so far.

Whenever I make an interactive form like this, I treat the form as a template, and use hooks to pre-fill values where I can. For example:

<input type=text name=first size=25 value=##value_first##>
<select size=1 name=color>
<option value=red ##selected_color_red##>
</select>

The, the PHP script will go through this template and replace anything in the ## pairs with appropriate values (as you can see, I'm naming them strategically so I can keep them straight in my mind. You can do it however you'd like).
posted by thanotopsis at 6:05 AM on August 24, 2005


When they insert "yellow" into the selection list, do you need the value "yellow" to get inserted into a database as well? Using some AJAX techniques would handle this.

Instead of having the "add-a-colour" box on a seperate page, make it its own form and put it next to the selection list in your form. When the add-a-colour form is submitted, fire off an xmlHttpRequest to post the color to a PHP page that inserts into your database. The PHP page then spits out some text (it doesn't really have to be XML) that says it was successful, and maybe a new list of all the colors in the database, which gets carried back to your form.

When that message gets carried back to your form, you trigger an event with some Javascript that clears the selection list and then rebuilds it using the list it got from the message.

There are AJAX libraries out there that can do the heavy lifting for you. Hope this makes sense.
posted by patgas at 6:35 AM on August 24, 2005


but that would mean a form with 2 submit buttons

So? These are quite common. Post the information to the add-a-colour page, put it in hidden INPUT tags in the form on that page. That form gets posted back to the original form page, and the script there recreates the form with the users initial values filled out, and the new category.

Very simple, no javascript necessary, and much more elegant and predictable from the users point of view.
posted by cillit bang at 7:20 AM on August 24, 2005


("the script there" means a script running on the server, obv.)
posted by cillit bang at 7:20 AM on August 24, 2005


AJAX is definitely the best way to go, but an easier way might be to have the selection list, plus a "add new color" textbox below it (maybe in an expanding DIV or something).

Then, when the form is submitted, either take the color they chose from the list, or if they typed a new color, add that and grab the ID before processing the rest of the form.

I think that's by far the easiest thing to do. If it sucks too much from a UI standpoint, then try to go the AJAX route.
posted by frufry at 7:21 AM on August 24, 2005


Cillit bang, that sounds like exactly the sort of thing I'm after. Maybe I'm being dim here... but how can I get submit-button 1 to submit the form, and submit-button 2 to take me to the add-a-colour page? I thought that the submit button just did what the form tag told it to, and as there's one form tag, there's one submit action.

or... should the two pages be one and the same script...?
posted by handee at 7:26 AM on August 24, 2005


Handee, you may be able to nest a new form inside the existing form with a different action to take you to the add-a-colour page. However, I'm not sure if the original values would be picked up. It seems that frufry's method would be easiest.
posted by tommyc at 7:43 AM on August 24, 2005


If Javascript is acceptible there are a number of ways you could skin this cat.

1. Have the "add color" be a normal link, with a JS event attached that takes the contents of the form fields, encodes/serializes them and stores them in a cookie before following the link. Then have JS in the main form page that checks for that cookie and fills in the fields with the unserialized data if present.

2. Have a seperate form with identical (but hidden) fields that mirror the fields in the main form. The second form's submit is the "Add color" button, with a JS event attached that copies the field data from the main form to this secondary form. Then your "Add color" script on the server would receive the partially-entered field data and it would be responsible for somehow sending them back to the main form page with that data present.

3. Some sort of asynchronous XMLRPC (ajax) method for adding colors that doesn't require leaving the page.

4. Have the "Add color" link be a normal link, but make it open in another window, perform whatever action is necessary, and then inject the result back into the main form (again using JS) such that whatever the user has entered is still there as the page hasn't reloaded. This kind of cross-window injection is normally not allowed by the browser for obvious security reasons, but I think it's possible when both windows are part of the same domain.
posted by Rhomboid at 7:59 AM on August 24, 2005


s/acceptible/acceptable/
posted by Rhomboid at 8:02 AM on August 24, 2005


Oh, and you should probably consider what happens if the user doesn't have JS or has it disabled. With #1 and #2 above, they will still be able to do everything but when returning to the form their previously entered data will be gone -- annoying but still usable. #3 and #4 would fail to even allow the user to add a color without JS, so they don't fall back as gracefully.
posted by Rhomboid at 8:06 AM on August 24, 2005


This kind of cross-window injection is normally not allowed by the browser for obvious security reasons, but I think it's possible when both windows are part of the same domain.

The browser should only choke when there are different domains involved. Otherwise, you can pass the original window's object ID to the child window, so that you can access its DOM at any time within the child window's procedure.
posted by thanotopsis at 8:06 AM on August 24, 2005


And, as an alternative to #2, you could probably just have two submit buttons -- the second having a JS event associated that changes the submit location before performing the action. That would allow it to go to the "add color" URL instead of the main submit URL, but without having to bother with two forms and copying data between fields.
posted by Rhomboid at 8:10 AM on August 24, 2005


I thought that the submit button just did what the form tag told it to, and as there's one form tag, there's one submit action.

Well, sure, but the script on the back end can check to see which submit button was clicked and behave appropriately.
posted by kindall at 8:57 AM on August 24, 2005


If I understand this correctly, you can do it with Javascript, and don't need XMLHttpRequest. Why go back to the server? Just create an array with value/display pairs for each of your default categories. Create a populateCategoryMenu() function that draws the menu based on the contents of the array. Call this function as an onLoad().

On the same page, have some sort of "...or add a new category:" option by the menu, with an input box and submit button. The submit button calls an addToCategoryMenu() function, which just appends the array, then calls populateCategoryMenu() to redraw the menu. Just make sure to return false at the end, so the form doesn't submit.
posted by mkultra at 10:09 AM on August 24, 2005


A much simpler solution, which is great in terms of programming AND usability, is to simply add a text field at the bottom of the select menu.

Whichever category that the user doesn't see in the menu, they can just key it into the text field below, eg "yellow". It's easily understood, and doesn't require any complications in JavaScript / AJAX / etc.

Once submitted, simply add the new item into your category table, and process the rest as usual.
posted by arrowhead at 10:05 PM on August 24, 2005


Maybe I'm being dim here... but how can I get submit-button 1 to submit the form, and submit-button 2 to take me to the add-a-colour page

You can't. They both go to the same script, which checks which button was pressed and acts appropriately.
posted by cillit bang at 3:36 AM on August 25, 2005


Thanks all - lots of good suggestions here.

I'm going to go for the simple option.
posted by handee at 1:38 AM on September 2, 2005


« Older I'm looking for literature th...   |   Excel - I am interviewing a co... Newer »
This thread is closed to new comments.


Related Questions
CodeFilter: July 24, 2008
Getting from point A to B (the right way) October 11, 2007
Other frameworks akin to Ruby on Rails? July 6, 2007
So I know HTML. What to learn next? December 10, 2006
Database-driven web sites using using Linux,... December 10, 2004