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).
|