Embedded below are the ways I approach these issues. As you will see, I'm NOT a
believer in doing the input processing in a JSP page -- I do it in a servlet
instead.
John G Kroubalkian wrote:
> Craig and all other JSP gurus,
>
> Q1: How do you handle page navigation for the multi-page input scenario?
>
> Example: A 3 page input layout
> Page 1: Has form for userFirstName, userLastName (separate Text Inputs)
> Page 2: Has form for homeStreetAddress, homeCity, homeState, homeZip
> (separate Text Inputs)
> Page 3: Has form for homeTelAreaCode, homeTelNumber, emailAddress (separate
> Text Inputs)
>
I build "Previous" and "Next" buttons like a typical "wizard" program, so the user
can go back and forth. The "Previous" button does not actually exist on the first
page, and the "Next" button is labelled "Done" on the last page. Each of these
buttons is actually a submit button with a different value, so that the receiving
servlet can tell which button was pressed.
In all cases the destination of the submit is a servlet designed to deal with all
of the pages of this input form.
>
> Q2: So the Bean could have String fields representing each of the form
> fields...3 separate forms. Correct?
>
That's the way I do it. The primary reason is that all of these properties are
logically related -- it is a presentation detail whether they are all on one page
or not. In fact, you can change your mind about that issue without affecting the
underlying logic if the fields are all in the same bean.
String fields are typical, but not required. For dates I normally use a
java.util.Date for the property, so that (when it get's redisplayed), it is
reformatted according to whatever date format I'm using no matter how the user
entered it.
>
> Q3: Here's a possible bean class...still on the right track?
> package com.mybeans;
> /**
> * This bean holds all information to be used in forms
> * Each attribute (property) has an associated getter/setter pair
> */
> public class UserInfoBean {
>
> public UserInfoBean() { //initialization...; }
>
> // Attributes/Members/Properties
> private String userFirstName;
> private String userLastName;
> ...
> }
>
Sounds good to me. One thing I do for string fields is initialize them to a zero
length string:
private String userFirstName = "";
instead of the default null value. Then, in the property setters (see next
answer), I convert a null argument to a zero length string. This lets you not
worry about unsightly "null" values in your JSP page when you do something like
this:
<input type="text" name="firstName"
value="<%= userInfoBean.getFirstName() %>">
In my instance variable declarations, I also initialize any default values that
are not zero-length strings. That way, the first time the user encounters page 1
(and there is no bean in existence yet), the <jsp:useBean> action will cause the
bean to be created with all the right default values.
>
> Q4: Now for some .JSP to specify the bean. This is placed at the very top of
> the .JSP page and in effect tells the JSP engine "Try to locate a session bean
> called "userinfo" of class "com.mybeans.UserInfoBean", if it does not exist,
> construct a new bean using the default (no-args) constructor. And, on
> creation set the properties as specified by the included <jsp:setProperty...>
> tags.
> <-- Create the bean -->
> <jsp:useBean id="userinfo" class="com.mybeans.UserInfoBean" scope="session">
> // <==Session ok?
> <jsp:setProperty name="userinfo" property="userFirstName" value="" />
> <jsp:setProperty name="userinfo" property="userLastName" value="" />
> <jsp:setProperty name="userinfo" property="homeStreetAddress" value="" />
> <jsp:setProperty name="userinfo" property="homeStreetCity" value="" />
> <jsp:setProperty name="userinfo" property="homeStreetState" value="" />
> <jsp:setProperty name="userinfo" property="homeStreetZip" value="" />
> <jsp:setProperty name="userinfo" property="homeTelAreaCode" value="" />
> <jsp:setProperty name="userinfo" property="homeTelNumber" value="" />
> <jsp:setProperty name="userinfo" property="emailAddress"
> value="[EMAIL PROTECTED]" />
> </jsp:useBean>
>
There's a couple of issues here. First, you need to define the usual getXxxx and
setXxxx methods in your bean, even if you're using pure JSP (see more on this
below). For example, you'd add methods like this to UserInfoBean for each
property:
public String getFirstName() {
return userFirstName;
}
public void setFirstName(String newFirstName) {
if (newFirstName != null)
userFirstName = newFirstName;
else
userFirstName = "";
}
Note that I'm ensuring the value of the first name property is never null, so I
can get away with the display syntax shown above.
Second, and more important -- in my designs, the "post" action for each of these
pages is a servlet, not a JSP page. Therefore, you would not have any of the
<jsp:setProperty> stuff -- the servlet will have filled all of that in already.
The servlet would have code like this (assume that the "pageId" parameter is a
hidden field that contains the page number we are currently on):
// Acquire the current UserInfoBean (or create one if needed)
HttpSession session = request.getSession();
UserInfoBean uib = (UserInfoBean) request.getValue("userinfo");
if (uib == null) {
uib = new UserInfoBean();
session.putValue("userinfo", uib);
}
// What page number submitted this form?
String pageId = (String) request.getParameter("pageId");
if (pageId == null) {
... deal with submit coming from an incorrect page ...
}
// Which submit button was pressed (Previous, Next, Done)?
String submit = request.getParameter("submit");
if (submit == null)
submit = "Next";
// Placeholder for the URL of the next JSP page to be executed
String nextId = null;
// Save the fields from this input form
if (pageId.equals("1")) {
uib.setFirstName(request.getParameter("userFirstName"));
uib.setLastName(request.getParameter("userLastName"));
// "Previous" is not supported on the first page
nextId = "/userinfo2.jsp";
} else if (pageId.equals("2")) {
uib.setStreetAddress(request.getParameter("userStreetAddress"));
...
if (submit.equals("Previous"))
nextId = "/userinfo1.jsp";
else
nextId = "/userInfo3.jsp";
} else if (pageId.equals("3")) {
uib.setHomeTelAreaCode(request.getParameter("userHomeTelAreaCode"));
...
if (submit.equals("Previous"))
nextId = "/userinfo2.jsp";
else
nextId = null; // Processing required
}
// If a "Next" or "Previous" button was selected, go to that page
if (nextId != null) {
RequestDispatcher rd =
getServletContext().getRequestDispatcher(nextId);
rd.forward(request, response);
return;
}
// Process the (completed) form. If there were any errors,
// forward to page 1, 2, or 3 appropriately with some means
// to display an error message. Otherwise, store the user
// (or whatever), and display a "done" page.
// You will normally want to remove the UserInfoBean from
// the session at this point, so that the next time the user
// returns to page 1 they will have a newly initialized UserInfoBean
// with default values again.
NOTE: My actual code is based on a framework that makes the above much more
organized -- the above is the result of ripping out all the actual logic and
putting it into something fairly easy to understand.
There are other ways to organize this stuff, but I've found that submitting to
servlets, doing the processing there, and forwarding to JSP pages for displaying
the results works best.
>
> Q5: Assuming a single .JSP is being hit, how do you deal with the page you're
> on? (In other words, there is a submit button on each page which points to
> the .JSP page)
>
Using a single JSP page for three different logical pages is poor design -- use
three pages instead.
>
> Q6: And how do you prevent yourself from having to try to access each (and
> every) form field on each pass through the page?
>
As above -- separate the pages.
>
> Q7: What would be the impact of moving a field (say, emailAddress from page
> 3) to a different page (say page 2)?
>
If you've got separated pages the way I've proposed it, you just move the <input>
tag, and modify your servlet by moving the single line of code (the one that calls
setEmailAddress()) from the if block for page 3 to the if block for page 2.
>
> Many Thanks,
> John
>
Craig
===========================================================================
To unsubscribe: mailto [EMAIL PROTECTED] with body: "signoff JSP-INTEREST".
FAQs on JSP can be found at:
http://java.sun.com/products/jsp/faq.html
http://www.esperanto.org.nz/jsp/jspfaq.html