Rick-
> When the user is presented with screen B, he fills out the
> search form and selects either:
>
> - OK: we process the search request and transition to screen C if
> search is successful, and return to screen B with errors if search
> is unsuccessful.
Actually, screen B and screen C are implemented in the same (.jsp)
file. When first moving from screen A to screen B, there are no
results stored in the context of the request. When screen B is
submitted to the Action, one of three things will happen.
- The results are stored in a "requestList" attribute
- The errors are stored in an "errorList" attribute
- A boolean "true" is stored in a "noResults" attribute
The .jsp displays the results as appropriate (using Struts logic
tags) under the same (form) header that was used to collect the
search criteria. This also allows the user to immediately do a
different search without hitting the "Back" button.
> - Cancel: we obtain the data from the cache, set things up,
> and return the user to screen A
Yes.
> - Hits the browser back button: ??
The browser simply restores screen A without any input from
the server. We never can directly discover whether or not this
has happened without the type of JavaScript I'm trying to avoid.
> When the user is presented with screen C, he either:
>
> - Selects a choice from the search results: we obtain the
> data from the cache, set things up, and return the user to
> screen A
Yes.
> - Hits the browser back button: ??
Again, the browser simply restores screen B without any input
from the server.
> So this leaves me with a couple of questions:
>
> 1. How do we differentiate the transitions when processing the
> OK or Cancel from screen B?
I look directly at the request. The relevant code is:
if (request.getParameter("cancel") != null)
{
LookupForm oldform = lkupform.getSavedForm();
return oldform.processAction(request, response);
}
(LookupForm is a derivative of ActionForm that has the small
amount of additional state information needed to implement the
stack.)
> I suppose this means the token used to store screen A's
> information is written to screen B's form, and retrieved IFF
> the user decides to Cancel screen B's action. True?
It's also used when the user selects a search result choice
on screen C.
> 2. What happens when the user selects a search result choice
> on screen C? We want to return the user to screen A. Does
> this mean that screen C should also be implemented as a HTML
> form, and that we also write the token for screen A to this
> form? How do you know which token to write onto screen C's
> form? Do you just "know" that screen B needs to create a new
> cache entry, and that screen C needs to use the cache entry
> token that is submitted with screen B's request, and therefore
> code it that way? Or do you have some other mechanism that
> you've designed?
Knowing that screens B and C share a .jsp and (by extension)
an ActionForm should make this a little clearer. The actual
selection of a search result from screen C is done with a custom
tag that references a "LookupResult" action which I reuse for
all such lookups. This tag
<app:lookupResult name="product" code="code" id="id">
produces this HTML
<a href="LookupResult.do?caller=4&code=CAC&id=36">
The caller is, again, a reference to the cached calling form.
The "code" and "id" are fields that identify the search result
chosen -- in this case, "code" is a human-readable possibly
unique value representing the record, and "id" is a surrogate
key to that record (and guaranteed unique).
The code is what will populate the field on the original form
(screen A) that we're looking up. The id allows for any
required disambiguation. (Usually, there is none.)
> When the back button is pressed, doesn't the previous page's
> request just get resent? What are the implications of this...
> any special processing required?
Back followed by submit will resend the previous request, yes.
I don't do anything special to handle this, and I don't think
there are any ramifications. (I'm pretty sure I worked it out
so that there is no memory leaked, but I'm fuzzy on the details.)
>> When the user clicks the "..." search, the entire calling state,
>> including the ActionForm bean, is copied into a cache which is
>> stored on a per-user basis.
>
> Can you share your code showing how you obtain all of the
> calling state? Also, your cache code, as well, if possible
I think I made that sound more sophisticated than it really is.
The calling state is just the calling ActionForm and Action.
The calling Action is what checks to see if the user has selected
the lookup in addition to its "real" processing job. It also
knows how to redraw the original screen.
I make frequent use of a pattern whereby there is a single action
and .jsp which are responsible for initially displaying the form,
displaying the form with any errors after a submission, going to
a lookup form, if that's what the user has clicked, and displaying
the output, which may be the same .jsp or a different one,
depending on the circumstances. I'm not 100% happy with this
pattern, and I'm sure that others will point out its shortcomings,
but it's been working for me so far.
I'll see what I can do about posting some code.
> By "moves forward", do you mean possibly moving up the stack
> of screens, e.g. from screen C to screen A?
I mean "moves forward" in the set of screens on the browser.
On the server, we'd be moving back up the stack of screens.
> Why do you have this short grace period? Is this cached
> information still relevant? Perhaps if the user hits forward
> and back again on the browser?
I think that yes, this was my motivation.
> For example, if we cache screen A's request information and
> then when we return the user to screen A after a successful
> search, we obtain that cached information (via the token stored on
> screen C), how will we know that cached information exists? I
> would have thought that the token (which should have disappeared
> after we processed screen C's request) was the only way to get
> the cached information from screen A's request.
I don't understand this. As long as the value still exists in
the cache, and the key to the value is stored someplace, we
can still get at the value. The key is just something that
we can pass back and forth to the browser as cheaply as possible.
>> If the user presses the "Back" button, the form remains in
>> the cache longer, although it, too, will eventually time out
>> and be destroyed.
>
> Huh?
I don't actually know that the browser's back button has been
pressed, and the small amount of memory involved doesn't make
it worth guessing.
--
Curt Hagenlocher
[EMAIL PROTECTED]