« Weblogic: ServletCon... | Main | Web continuations... »

Web continuations, breadcrumbs, and picking up where you left off.

Often in web applications, a user will be filling in an HTML form on one page and will realize the need to go to a second or even a third page to enter information needed by the first page.

For example, you are writing a weblog entry by typing text into an HTML form on the Edit Weblog Entry page. You type in about half of your entry and then you realize that you need to create a new category for your post. You click the Add Weblog Category button, arrive at the Add Weblog Category page, create your new Category, and click OK. At this point, you are returned to the Edit Weblog Entry page to find that your half-edited weblog entry is still there. You are ready to continue right where you left off.

How do you achieve this type of behavior in your web application? How do you allow users to continue working where they left off? Do you treat each case as a special case or do you have a general solution like a breadcrumb stack or a web continuation to this problem? It can get pretty messy. Do you cache half-completed forms in your HTTP session or in your database? Or, do you avoid the whole issue by carefully designing around it.

Comments:

Yahoo mail solves this problem in a way I like. When you start composing an email, then add attachment, you get sent to a new "Add Attachment" page. It stores what you've entered for your email in hidden fields on the "Add Attachment" page. <p/>I like this approach a lot because <div>1. It doesn't take up additional memory on the server</div <div>2. There's no confusion about tracking which info belongs to which user, and when to show it again (how do you know on the New Entry page whether to show stuff they were working on before, or to start an empty new entry?)</div> <div>3. There's no irritating situation where usually your entry is saved...unless you walk away from your computer to do something else, and the info gets timed out on the server...in which case you unexpectantly lose your entry.</div>

Posted by Will Gayther on November 12, 2003 at 03:16 PM EST #

Will, <p /> The add-attachment use case is a pretty simple example. It is simple because the Compose-Email page is the only page that allows you to get to the Add-Attachment page. <p /> What if you could add attachments to calendar entries and todo list items? Would you add all of the fields from the Create-Calendar-Entry and Create-ToDoList-Item forms as hidden fields on the Add-Attachment form. That sounds pretty messy. And, how do you know which page to return to when the use is done adding the attachment? <p /> - Dave

Posted by Dave Johnson on November 12, 2003 at 03:45 PM EST #

<p/>Addding all those fields isn't messy if you remember that you can generate hidden form fields on the fly - the page attachment page doesn't need to have set hidden fields, it can have whatever hidden fields are appropriate based on what fields were submitted to it. And you know which page to return to when you're done adding attachments because the url of that page is just another hidden field. Here's the long explanation below: <p/>Here's how I would think it would work. From my example of an email system: <p/>The Compose page would either have empty fields, or have default data in those fields if certain parameters were passed to it (messageSubject, messageText, messageToField, etc). <p/>The Add Attachment page would store all the parameters passed to the page in hidden fields in the form (you could not store the parameters specific to the Add Attachment page to save space), as well as storing a final submit target which is another parameter passed to it. <p/>It would work like this: The user starts at the compose page, which is blank. They enter some information, then click on the Add Attachment link (which is actually a form which submits the data they've entered). This takes them to the Add Attachment page. On the server, all the data submitted is put in hidden fields (where the name is the parameter name, and the value is the value)., including the final submit target. When the user submits the page, first it goes to the AddAttachment target. This adds the attachment, then does a <jsp:forward/> to the final submit target (in this case it would be the compose page) which, because there are parameters like messageSubject, messageText, messageToField knows to take those values and display them as the default values for the fields for Compose Message. <p/>The Compose page knows what parameters to look for (or you could add a special field to indicate which kind of data is being passed around) to display for a half written entry. The Add Attachment page simply stores extra parameters passed to it in hidden fields without knowing what those parameters mean, and those parameters then eventually get forwarded back to the page that sent them in the first place. <p/>Do you see how this would allow you to add many other pages that would add an attachment by submitting info to the Add Attachment page with a final submit target of themselves, and all the data would get passed around in hidden fields without anything needing to be stored on the server?

Posted by Will Gayther on November 12, 2003 at 04:58 PM EST #

Good questions. My favorite ultimate solution involves web continuations, as implemented by FlowScript in Cocoon 2.1+ The ability to write a small function which, at points in the function code, can send out a web page and then pick up where it left off, is just damn powerful and very intuitive. One of these days, I or someone else should port that to Struts :)

Posted by Don Brown on November 12, 2003 at 05:03 PM EST #

somewhere out on the wild web I saw someone who was using javascript for the back and forth buttons, which just hid and unhid the parts of the form you were working on. Not optimal, but it would work well with no server load and hold the data. I can see it confusing people trying to use the back button though.

Posted by John Beimler on November 12, 2003 at 05:45 PM EST #

The latest pre-release version of RIFE has support for web continuations in regular java classes. It achieves this through on-the-fly byte-code modification during class loading. Note that this is a pre-release and some bugs have been identified already. I'm tending to them at this very moment and it should be stable and ready for a real release somewhere next week. Don't hesitate to contact me or the mailinglist for further questions.

Posted by Geert Bevin on November 13, 2003 at 07:51 AM EST #

This is simply done by having a session scoped object that contains all the information that spans the pages of the form.

Posted by Robert Nicholson on November 13, 2003 at 12:32 PM EST #

Did my explanation make sense Dave? Or was there something wrong with it?

Posted by Will Gayther on November 13, 2003 at 03:10 PM EST #

Yes Will, your comment made sense. I think a workable solution could be created using only dynamically generated hidden form fields as you suggest.

Posted by Dave Johnson on November 13, 2003 at 04:21 PM EST #

<!-- This is the Struts configuration file for the example application, using the proposed new syntax. --> <struts-config> <!-- ========== Form Bean Definitions =================================== --> <form-beans> <form-bean name="parameterForm" type="ericsson.mma.framework.configuration.ParameterForm"/> <form-bean name="importForm" type="ericsson.mma.framework.configuration.ImportForm"/> <form-bean name="exportForm" type="ericsson.mma.framework.configuration.ExportForm"/> <form-bean name="createForm" type="ericsson.mma.services.blogging.CreateForm"/> <form-bean name="loggerForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="level" type="java.lang.String" /> <form-property name="additivity" type="java.lang.Boolean" /> </form-bean> <form-bean name="appenderForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="appenderName" type="java.lang.String" /> <form-property name="appenderClass" type="java.lang.String" /> <form-property name="layoutClass" type="java.lang.String" /> </form-bean> </form-beans> <!-- ========== Global Exception Definitions ============================ --> <global-exceptions> </global-exceptions> <!-- ========== Global Forward Definitions ============================== --> <global-forwards> <forward name="showErrorPage" path="/WEB-INF/jsp/framework/ErrorPage.jsp" /> </global-forwards> <!-- ========== Action Mapping Definitions ============================== --> <action-mappings>

Posted by Unknown on December 01, 2003 at 03:05 PM EST #

Post a Comment:
  • HTML Syntax: NOT allowed

« Weblogic: ServletCon... | Main | Web continuations... »

Welcome

This is just one entry in the weblog Blogging Roller. You may want to visit the main page of the weblog

Related entries

Below are the most recent entries in the category Java, some may be related to this entry.