Building an AJAX Application (3): how to submit a form "silently"?




Introduction


A major goal using AJAX (precisely, Remote Scripting) is to minimize page
reload. Form submission is the major way to communicate with server in a traditional web 
page. Let's take a look at a concrete and very common example, say Example A Show details):
   
a list frame and editing frame. The list frame displays available records while editing frame 
allow you to modify the selected record in the list. 

The issue we are concerning is "how do we submit the form in the editing frame?"
Let's compare different approaches:

  • The traditional way: submit the form directly.
  • You may say, we have been using this way for years. What is wrong with it? Yes, here are the problems: a). Empty pages. Some browsers clean up the old content in a page before they load new content. In case it takes browser a long time to process/load or network latency is big (you may see this ofen during a remote conference), you can see the web page appear empty for a while. This is not just "looking bad" but also cause users to click at the submit button again in case the submit button reside outside of the page or click at the refresh button of the browser and causes double submission problem in case you don't have double submision protection. A typical screen you can see this appearance is My scroll table page, in IE (you won't see this in FireFox, Mozilla/Netscape and Opera), where you will see a empty page after you click at a page number in the pagination area or change the size of page. b). Screen state lost. A big difference between a web page and a screen in a regular Windows application is that Windows app screen never lose its screen state such as the focus field, cursor position, highlighted text and so on while all these states are lost when a web page is reloaded (the case you need to load the same page back with new content). Why do we need to preserve the screen state? Let's look at a concrete example. In 1997, I involved the development of the AR WebPlus System in Remedy (responsible on designing and implementing the major search page). This is the web version of their Windows AR. One of the major requirements for its major search page was allowing users keep typing and load search result based on what they had entered when they hit enter key. The challenge was that users still keep typing after they hit enter key. In this case, if I refreshed the search page(causing screen state lost), users would lose their typing environment. You may think that you can recover the state after reloading. The problem was that in case of a significant network latency users will face the white screen and more importantly, they want to "keep typing while the rest of fields are graduately filled up". The solution was Remote Scripting using static hidden frames (so many years before AJAX was formally out). The page where users were typing was never reloaded while only fields in the page were updated by the search result return in hidden frame, appearing just like a windows application! c). Exception handling. What if something goes wrong or validation fails at the server side? Since the form is submited from the editing frame so the response has to be return to the editing frame. A very old approach is to display a error page (by default provided by servlet) in editing frame. This is really bad since the state of the page is lost. The first thing most users react on this is to click at the back button trying to recover the page state. In many of case, you don't want the back button to be the mean recovering the previous state. Here is how to try this Back Button problem out: - Click at following link to open a window with Example A mentioned above Click here to see the form page. - select a row in the upper frame, the list frame. This will load the selected row into the lower frame, the editing frame. - now click at button "Save with Exception". What this button does is make NumberFormatException in the editing jsp and an error page is displayed. A later solution is to post back the original page with problem fields marked red. There are some issues on this solution. For example, The newly loaded form with red marks will be added into browser's history. So in case user want to "go back", they will see the pages with red marks before they can really reach the previous page. Here is how to try it out: - Click at following link to open a window with a link to Example A mentioned above Solution of the Back Button problem - click at the link "Click here to see the form page" to move to the Example A page. - select a row in the upper frame, the list frame. This will load the selected row into the lower frame, the editing frame. - now click at button "Save with Invalid fields". What this button does is make one of the field contain a space only, that is not allowed by the validator at the server side so the form is post back with invalid fields red. Keep click at the button several times and you will see several invalid fields. - Say, then you want to go back to the first page where you come from to Example A page. So you click at back button of the browser. The result is that you won't be able to go back to the first page right away before going through all your mistake pages. d). Resource wasting. In some pages, the form is only a small section. Reloading the entire page not only load the new content for the form but also reload the rest of the page (unchanged content). It cost more server cpu time to republish them and cost network bandwidth to transfer them.
  • The silent way: submit the form indirectly.
  • Instead of posting the form directly, we can post it "asynchronizely" using Remote Scripting. The original form is never reloaded. Here is the corresponding issues: a). No "Empty pages". Since the response is never return to the editing frame so its content is never cleaned by browsers. Click at save to see how "silent" it is when the list frame is updated while the editing frame is never touched. To try: - select a row in the list - then enter some data in field other than the first field (it is used as an id field). - click at save to see how "silent" the list is updated. See the demo of this approach here b). No more screen state lost since the page is never reloaded. c). Great "Exception handling". In case of exception or validation failure, the editing frame is never "touched" by the browser so there is no history for exception screens so there is no state to be lost and of course, there is no state to be preserved. (In case of Hidden frame, I need to "erase" the history to make it up)." Still remember the problem? Try the same step again: click at the "Save with Invalid fields" button several times and then click at the back button. The first page linked to Example A You will see no "garbage history" - back button will take you instantly back to the previous page. Different browser behave a little bit differently, specially Mozilla Family. d). No "Resource wasting". Javascript submits the request and update whatever we need to update precisely. e). Update any part of the frame or any frame. Try the field "Update" and you will see the list frame is update "silently" if choosing "List Frame". Try it: See the demo of this approach here Note: don't forget to try different "Transport" and you will see "Cookie" doesn't work if you select "Update List" since its limitation is always reached even a single row a page. You can also verify if a transport is really used by like turning off ajax (activeX).