PDA

View Full Version : AbstractWizardFormController back button (_target=1)



pg
Sep 3rd, 2004, 06:19 AM
This should have a simple solution but I am just too thick.

I have got an AbstractWizardFormController working fine after following the jpetstore OrderFormController.java example.

I want to have a back (previous page) button on my pages. Therefore I add something similar to the following in the jsp:

<a class="buttonLink" href="<c:url value="/addjob.htm?_target=0"/>"><input type="button" alignment="center" value="back" /></a>

where: /addjob.htm refers to the controller.

In the controller I add: request.getParameter(PARAM_TARGET) != null to the isFormSubmission method, as follows:

protected boolean isFormSubmission(HttpServletRequest request) {
return super.isFormSubmission(request)
|| request.getParameter(PARAM_FINISH) != null
|| request.getParameter(PARAM_CANCEL) != null
|| request.getParameter(PARAM_TARGET) != null;
}

In the getTargetPage I add:

protected int getTargetPage(HttpServletRequest request, Object command, Errors errors, int currentPage) {
if (request.getParameter(PARAM_TARGET) != null) {
return Integer(request.getParameter(PARAM_TARGET)).intVal ue();
}
if (currentPage == 0) {
return 1;
}
else {
return 2;
}
}

This works fine for the first time a back button is pressed. After this the ?_target=0 remains in the request and it is not possible to move to another page other than the one specified in the _target.

Shouldn't the request clear automatically?

pg
Sep 21st, 2004, 07:03 AM
After a long break from this problem and cleaning up the code it seems that the issue below is not there anymore. (Note I also got a later Spring framework download).

Not a very satisfactory post so ignore the above issue.

There is still a problem in that if you go backwards then forwards and backwards again. In otherwords the _target= number has not changed the formBackingObject method is run and a new view starting at page 0 is created.

This can be programmed around but it would appear that this is not the correct behaviour.

gmatthews
Sep 21st, 2004, 06:16 PM
Using the scenario that you're currently on page 3 (i.e. _target2), to put a back button on the page you just need to do this:

<input type="submit" name="_target1" value="Back">

That's it. No special controller code needed.

If you wanted to have a Buttons.jsp or something that contained Next/Prev/Finish/Cancel buttons that typically appear in wizards then you can set the pageAttribute controller bean property, which tells Spring what name to publish the current page number under.

Other assumption is that you're using AbstractWizardFormController.

If you want to do something different like go back to a completely different page, then you probably want to maintain a history of where the user has been and need to create an interceptor in front of your controllers to track URLs, etc,

pg
Sep 23rd, 2004, 04:35 AM
Thanks for the response. I am using the AbstractWizardFormController.

I have tried:

<input type="submit" name="_target1" value="Back">

but it just submits the form and goes to the next page having passed through the getTargetPage() method.

It works the way I have written with the one exception. That is:

1) going forwards to next page
2) going backwards to previous page
3) going forwards to next page
4) going backwards to previous page

step 4) causes the formBackingObject() method to be run and creates a new form. This, I believe, is due to the fact that the _target=1 where 1 represents the previous page remains in the request string after step 2). If the request string changes e.g. _target=2 because you have moved forwards after step 3) and then moved backwards evereything is fine.

As I say unfortunately the mechanism you suggest does not work although if it did it would solve this problem since the move to the previous and next page would be handled consistently (i.e. through the submit input).

gmatthews
Sep 23rd, 2004, 04:44 AM
Hi pg,

I'm pretty sure it does work. Let's try to sort this out. Here's some related comments that might hopefully sort out the prob.

1. wizard pages use a zero based numbering scheme., so "_target0" is the first page.

2. you have to use POST, not GET to navigate between pages.

3. if you wanted for example to move through pages of a wizard, you'd have to submit variables named "_target1", "_target2", "_target3", and so on, so the Next and Prev buttons on each page have to change the "_target<n>" inputs. You can specify the "pageAttribute" property in the controller to publish the current page number, and then use JSTL to dynamically set the target for Next and Prev.

Try posting your controller bean xml definition, JSP page and Java controller code if this still doesn't work.

good luck.

pg
Sep 23rd, 2004, 05:15 AM
Thanks gmatthews,

It was my getTargetPage() method which was getting in the way. Removal of this solved the problem. The mixing up of POST and GET was my confusion.

Everythings working fine, thanks again.

delnoij
Nov 22nd, 2004, 06:09 AM
Does that mean that when relying on Spring's internal mechanism for mapping request parameter names to Views:



<input type="submit" name="_target1" value="Back">

the getTargetPage() method should not be overridden?

pg
Nov 22nd, 2004, 07:37 AM
When I left the getTargetPage() method alone things worked fine.

delnoij
Nov 23rd, 2004, 05:01 AM
PG, is it possible that you would post your current controller code + code snippets of the jsp's defining the buttons?

pg
Nov 23rd, 2004, 03:07 PM
Here is the controller I have it is a bit long:

package com.bluestoneworks.web;

//import java.sql.Time;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
//import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.propertyeditors.CustomDa teEditor;
import org.springframework.beans.propertyeditors.CustomNu mberEditor;
//import org.springframework.beans.propertyeditors.Properti esEditor;
//import org.springframework.context.support.MessageSourceA ccessor;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.servlet.mvc.AbstractWizard FormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.bind.ServletRequestDataBin der;

import com.bluestoneworks.bus.AddJob;
import com.bluestoneworks.bus.AddJobValidator;
import com.bluestoneworks.bus.JobManager;

/**
* Add job multi page form controller
*
* @author Paul Green
*
*/
public class AddJobFormController extends AbstractWizardFormController {

/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());

private JobManager jobMan;

private String successView;
private String failureView;

/**
* constructor
*
* Need to specify the command name and pages to be used in the multi page form
*
*/
public AddJobFormController() {
setCommandName("addJob");
setPages(new String[] {"quickquotepage0", "quickquotepage1", "quickquotepage2", "contactdetails", "checkaddress", "departure", "arrival", "passengers", "summary", "termsandconditions", "addjobfinish"});
}

/**
* This is run before the form is created
* @param request - HttpServletRequest
* @throws ServletException
*/
protected Object formBackingObject(HttpServletRequest request) throws ServletException {

AddJob addJob = new AddJob();
// initialise no departure to false
addJob.setNoDeparture(new Boolean(Boolean.FALSE.booleanValue()));
return addJob;
}

/**
* Set up custom property editors for the application
* specify the valid formats for specific field and / or types
* @param request - HttpServletRequest
* @param binder - ServletRequestDataBinder
*/
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
// date format
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, null, new CustomDateEditor(dateFormat, true));

// time formats actually using date format and will have to convert
// prior to entry into the database
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
timeFormat.setLenient(false);
binder.registerCustomEditor(null, "flightTime", new CustomDateEditor(timeFormat, true));
binder.registerCustomEditor(null, "checkInTime", new CustomDateEditor(timeFormat, true));
binder.registerCustomEditor(null, "departurePickupTime", new CustomDateEditor(timeFormat, true));
binder.registerCustomEditor(null, "arrivalPickupTime", new CustomDateEditor(timeFormat, true));

// number formats
binder.registerCustomEditor(null, "numberOfBoosterSeats", new CustomNumberEditor(Integer.class, true));
binder.registerCustomEditor(null, "numberOfChildSeats", new CustomNumberEditor(Integer.class, true));
binder.registerCustomEditor(null, "numberOfBabySeats", new CustomNumberEditor(Integer.class, true));
binder.registerCustomEditor(null, "numberOfPassengers", new CustomNumberEditor(Integer.class, false));
// binder.registerCustomEditor(null, "checkInTimeHoursBeforeFlightTime", new CustomNumberEditor(Integer.class, true));
}

/**
* Determine if the given request represents a form submission
* @param request - HttpServletRequest
* @return boolean
*/
protected boolean isFormSubmission(HttpServletRequest request) {
// page name into request for index highlighting (left hand column index)
// nothing to do directly with this page
request.setAttribute("indexPageName", "addJob");

return super.isFormSubmission(request) || request.getParameter(PARAM_FINISH) != null
|| request.getParameter(PARAM_CANCEL) != null;
}

/**
* Callback for custom post-processing in terms of binding and validation
* Called on each submit, after standard binding but before page-specific validation of this wizard form controller.
* @param request - HttpServletRequest. current HTTP request
* @param command - Object. bound command
* @param errors - BindException. Errors instance for additional custom validation
* @param page - int. current wizard page
* @throws Exception. in case of invalid state or arguments
*/
protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors, int page)
throws Exception {
// if (page == 0 && request.getParameter("shippingAddressRequired") == null) {
// OrderForm orderForm = (OrderForm) command;
// orderForm.setShippingAddressRequired(false);
// }
}

/**
* Create a reference data map for the given request, consisting of bean name/bean instance pairs as expected by ModelAndView
* Overrides referenceData in class AbstractFormController
* @param request - current HTTP request
* @param page - current wizard page
* @return - a Map with reference data entries, or null if none
* @throws Exception - in case of invalid state or arguments
*/
protected Map referenceData(HttpServletRequest request, int page) throws Exception {
if (page == 1) {
// get list of local airports with associated prices
List airportsWithPrices = new ArrayList();
airportsWithPrices.add("");
airportsWithPrices.addAll(getJobManager().getAirpo rtsWithPrices());
// get list of area postcodes with associated prices
List areaPostcodesWithPrices = new ArrayList();
areaPostcodesWithPrices.add("");
areaPostcodesWithPrices.addAll(getJobManager().get AreaPostcodesWithPrices());
Map model = new HashMap();
model.put("airportsWithPrices", airportsWithPrices);
model.put("areaPostcodesWithPrices", areaPostcodesWithPrices);
return model;
}

if (page == 2) {
// this is post processing after validation
// it has been put here for want of a better place (should it go somewhere else?)
// calculate price
AddJob addJob = (AddJob)request.getSession().getAttribute("com.bluestoneworks.web.AddJobFormController.form.a ddJob");
logger.info(addJob.getQuickQuoteAirportSelected() + "," + addJob.getQuickQuotePostcodeArea() + "," + addJob.getNumberOfPassengers());
// Double price = getJobManager().getJourneyPrice(addJob.getQuickQuo teAirportSelected(), addJob.getQuickQuotePostcodeArea(), addJob.getNumberOfPassengers());
List prices = getJobManager().getJourneyPrices(addJob.getQuickQu oteAirportSelected(), addJob.getQuickQuotePostcodeArea(), addJob.getNumberOfPassengers());
Double price = new Double(0.0);
Double exclusivePrice = new Double(0.0);
Double onewayPrice = new Double(0.0);
Double onewayExclusivePrice = new Double(0.0);
if (prices.size() > 0) {
price = (Double)prices.get(0);
exclusivePrice = (Double)prices.get(1);
onewayPrice = (Double)prices.get(2);;
onewayExclusivePrice = (Double)prices.get(3);;
}
logger.info("price set to " + price);
if (addJob.getOneWayJourney().booleanValue()) {
if (addJob.getExclusiveTravel().equalsIgnoreCase("y")) {
addJob.setPrice(onewayExclusivePrice);
addJob.setComparisonPrice(onewayPrice);
}
else {
addJob.setPrice(onewayPrice);
}
}
else {
if (addJob.getExclusiveTravel().equalsIgnoreCase("y")) {
addJob.setPrice(exclusivePrice);
addJob.setComparisonPrice(price);
}
else {
addJob.setPrice(price);
}
}
}

if (page == 4) {
// fill in address for client to check
AddJob addJob = (AddJob)request.getSession().getAttribute("com.bluestoneworks.web.AddJobFormController.form.a ddJob");
addJob.setAddress(getJobManager().getAddressFromPo stcode(addJob.getPostcode()));
}

// if (page == 5) {
// // this is post processing after validation
// // it has been put here for want of a better place (should it go somewhere else?)
// // set check-in time and pickup time based on flight time
// AddJob addJob = (AddJob)request.getSession().getAttribute("com.bluestoneworks.web.AddJobFormController.form.a ddJob");
// Date flightTime = addJob.getFlightTime();
// Integer checkInTimeHoursBeforeFlightTime = addJob.getCheckInTimeHoursBeforeFlightTime();
// if (checkInTimeHoursBeforeFlightTime == null) {
// checkInTimeHoursBeforeFlightTime = new Integer(2);
// }
// checkInTimeHoursBeforeFlightTime = new Integer(checkInTimeHoursBeforeFlightTime.intValue( ) - 2);
// addJob.setCheckInTime(subtractHours(flightTime, checkInTimeHoursBeforeFlightTime.intValue() + 2));
// addJob.setDeparturePickupTime(subtractHours(flight Time, checkInTimeHoursBeforeFlightTime.intValue() + 4));
// }

if (page == 8) {
// show warning message if arrival is before departure
// and if either the departure or arrival dates are greater than one year ahead
Boolean warnMsg = new Boolean(Boolean.FALSE.booleanValue());
Boolean warnDepartOneYearMsg = new Boolean(Boolean.FALSE.booleanValue());
Boolean warnArrivalOneYearMsg = new Boolean(Boolean.FALSE.booleanValue());
AddJob addJob = (AddJob)request.getSession().getAttribute("com.bluestoneworks.web.AddJobFormController.form.a ddJob");
if (addJob.getArrivalDate() != null && addJob.getDepartureDate() != null) {
if (addJob.getArrivalDate().before(addJob.getDepartur eDate())) {
warnMsg = new Boolean(Boolean.TRUE.booleanValue());
}
}
if (addJob.getDepartureDate() != null) {
if (validateDate(addJob.getDepartureDate(), 365)) {
warnDepartOneYearMsg = new Boolean(Boolean.TRUE.booleanValue());
}
}
if (addJob.getArrivalDate() != null) {
if (validateDate(addJob.getArrivalDate(), 365)) {
warnArrivalOneYearMsg = new Boolean(Boolean.TRUE.booleanValue());
}
}
// check if valid flight number based on flight letter in db
Boolean warnDepartFlightNumberMsg = new Boolean(Boolean.FALSE.booleanValue());
String depFlightNum = addJob.getDepartureFlightNumber();
if (depFlightNum != null) {
if (depFlightNum.length() > 0) {
depFlightNum.trim();
// also need some numbers and possibly a letter at the end
Pattern p = Pattern.compile("^.*\\d+\\s*[a-zA-Z]?$");
Matcher m = p.matcher(depFlightNum);
if (!jobMan.checkFlightLetter(depFlightNum).booleanVa lue() ||
!m.matches()) {
warnDepartFlightNumberMsg = new Boolean(Boolean.TRUE.booleanValue());
}
}
}
// check if valid flight number based on flight letter in db
Boolean warnArrivalFlightNumberMsg = new Boolean(Boolean.FALSE.booleanValue());
String arrFlightNum = addJob.getArrivalFlightNumber();
if (arrFlightNum != null) {
if (arrFlightNum.length() > 0) {
arrFlightNum.trim();
// also need some numbers and possibly a letter at the end
Pattern p = Pattern.compile("^.*\\d+\\s*[a-zA-Z]?$");
Matcher m = p.matcher(arrFlightNum);
if (!jobMan.checkFlightLetter(arrFlightNum).booleanVa lue() ||
!m.matches()) {
warnArrivalFlightNumberMsg = new Boolean(Boolean.TRUE.booleanValue());
}
}
}
Map model = new HashMap();
model.put("warnArrivalBeforeDepartureMsg", warnMsg);
model.put("warnDepartOneYearMsg", warnDepartOneYearMsg);
model.put("warnArrivalOneYearMsg", warnArrivalOneYearMsg);
model.put("warnDepartFlightNumberMsg", warnDepartFlightNumberMsg);
model.put("warnArrivalFlightNumberMsg", warnArrivalFlightNumberMsg);
return model;
}

return null;
}

/**
* Validate date is at least a certain number days after today
* @param requestDate - Date requested to test
* @param numberOfDays - number of days ahead
* @return boolean true if a certain number days after today false if not
*/
private boolean validateDate(Date requestDate, int numberOfDays) {
boolean returnVal = false;
if (requestDate != null) {
Date currentDate = new Date();
logger.info("requestDate is " + requestDate);
Calendar currentCal = new GregorianCalendar();
currentCal.setTime(currentDate);
Calendar testDate = new GregorianCalendar(currentCal.get(Calendar.YEAR), currentCal.get(Calendar.MONTH), currentCal.get(Calendar.DATE));
// add specified number of days to current date
testDate.add(Calendar.DATE, numberOfDays);
logger.info("testDate.getTime() is " + testDate.getTime());
if (!requestDate.before(testDate.getTime())) {
returnVal = true;
}
}
return returnVal;
}

// /**
// * subtract specified number of hours from specified time
// * @param timeToSub - Date to subtract specified hours
// * @param numberOfDays - number of hours to subtract
// * @return String representation of the time HH:mm with subtracted hours
// */
// private String subtractHours(Date timeToSub, int numberOfHours) {
// String returnTime = "00:00";
// logger.info("timeToSub is " + timeToSub);
// if (timeToSub != null) {
// Calendar startDate = new GregorianCalendar();
// startDate.setTime(timeToSub);
// startDate.add(Calendar.HOUR_OF_DAY, - numberOfHours);
// String hr = new Integer(startDate.get(Calendar.HOUR_OF_DAY)).toStr ing();
// String min = new Integer(startDate.get(Calendar.MINUTE)).toString() ;
// if (hr.length() < 2) {
// hr = new String("0").concat(hr);
// }
// if (min.length() < 2) {
// min = new String("0").concat(min);
// }
// returnTime = hr.concat(":").concat(min);
// logger.info("returnTime is " + returnTime);
// }
// return returnTime;
// }

// /**
// * subtract specified number of hours from specified time
// * @param timeToSub - Date to subtract specified hours
// * @param numberOfDays - number of hours to subtract
// * @return Date the new date with subtracted hours
// */
// private Date subtractHoursDate(Date timeToSub, int numberOfHours) {
// Date returnTime = timeToSub;
// logger.info("timeToSub date format is " + timeToSub);
// if (timeToSub != null) {
// Calendar startDate = new GregorianCalendar();
// startDate.setTime(timeToSub);
// startDate.add(Calendar.HOUR_OF_DAY, - numberOfHours);
// returnTime = startDate.getTime();
// logger.info("returnTime date format is " + returnTime);
// }
// return returnTime;
// }

/**
* Method for custom validation logic for individual pages
* @param command - form object with the current wizard state
* @param errors - validation errors holder
* @param page - number of page to validate
*/
protected void validatePage(Object command, Errors errors, int page) {
AddJob addJob = (AddJob) command;
AddJobValidator addJobValidator = (AddJobValidator) getValidator();
switch (page) {
case 0:
addJobValidator.validateExclusiveOrShared(addJob, errors);
break;
case 1:
addJobValidator.validateQuickQuote(addJob, errors);
break;
case 3:
addJobValidator.validateContactDetails(addJob, errors);
break;
case 4:
addJobValidator.validateAddress(addJob, errors);
break;
case 5:
addJobValidator.validateDepartureJourneyDetails(ad dJob, errors);
break;
case 6:
addJobValidator.validateArrivalJourneyDetails(addJ ob, errors);
break;
case 7:
addJobValidator.validateChildSeats(addJob, errors);
break;
case 9:
addJobValidator.validateAcceptTermsAndConditions(a ddJob, errors);
break;
}
}

/**
* Method for processing the final action of this wizard
* @param request - current HTTP request
* @param response - current HTTP response
* @param command - form object with the current wizard state
* @param errors - validation errors holder
* @return the finish view
* @throws Exception - in case of invalid state or arguments
*/
protected ModelAndView processFinish(HttpServletRequest request, HttpServletResponse response,
Object command, BindException errors) throws Exception {
logger.info("processFinish");
AddJob addJob = (AddJob) command;
// not populating database at this stage
// if (addJob.getAcceptTermsAndConditions().booleanValue ()) {
// MessageSourceAccessor msa = getMessageSourceAccessor();
// jobMan.createSaveJob((AddJob)command, msa, request);
// }

// Map model = new HashMap();
// model.put("message", "Thank you, your order has been submitted.");
// return new ModelAndView("ViewOrder", model);
// create a new HashMap to pass to a form which will
// submit the data to WorldPay site
Map model = new HashMap();
if (addJob.getAcceptTermsAndConditions().booleanValue ()) {
int jobNo = jobMan.getNextJobNumber();
logger.info("job number set to " + jobNo);
model.put("jobNo", new Integer(jobNo));
model.put("name", addJob.getName().trim());
model.put("telNo", addJob.getTelNo().trim());
String telNo2 = addJob.getTelNo2();
if (telNo2 != null) {telNo2 = telNo2.trim();}
model.put("telNo2", telNo2);
model.put("email", addJob.getEmail().trim());
// take 5% discount off price
Double price = addJob.getPrice();
price = new Double(price.doubleValue() - (price.doubleValue() * 0.05));
// rounding to 2 decimal places
BigDecimal bd = new BigDecimal(price.doubleValue());
bd = bd.setScale(2, BigDecimal.ROUND_DOWN);
price = new Double(bd.doubleValue());
model.put("price", price);
model.put("exclusiveTravel", addJob.getExclusiveTravel());
model.put("oneWayJourney", addJob.getOneWayJourney());
model.put("noDeparture", addJob.getNoDeparture());

model.put("quickQuoteAirportSelected", addJob.getQuickQuoteAirportSelected());
model.put("numberOfPassengers", addJob.getNumberOfPassengers());

String foreignAirport = addJob.getForeignAirport();
if (foreignAirport != null) {foreignAirport = foreignAirport.trim();}
model.put("foreignAirport", foreignAirport);
model.put("departureDate", DateToString(addJob.getDepartureDate()));
model.put("flightTime", TimeToString(addJob.getFlightTime()));
model.put("checkInTime", TimeToString(addJob.getCheckInTime()));
model.put("departurePickupTime", TimeToString(addJob.getDeparturePickupTime()));
String departureFlightNumber = addJob.getDepartureFlightNumber();
if (departureFlightNumber != null) {departureFlightNumber = departureFlightNumber.trim();}
model.put("departureFlightNumber", departureFlightNumber);
model.put("numberOfBoosterSeats", addJob.getNumberOfBoosterSeats());
model.put("numberOfChildSeats", addJob.getNumberOfChildSeats());
model.put("numberOfBabySeats", addJob.getNumberOfBabySeats());

model.put("arrivalDate", DateToString(addJob.getArrivalDate()));
model.put("arrivalPickupTime", TimeToString(addJob.getArrivalPickupTime()));
String arrivalFlightNumber = addJob.getArrivalFlightNumber();
if (arrivalFlightNumber != null) {arrivalFlightNumber = arrivalFlightNumber.trim();}
model.put("arrivalFlightNumber", arrivalFlightNumber);

model.put("address", addJob.getHouseNumberName().trim() + ", " + addJob.getAddress());
model.put("postcode", addJob.getPostcode());

return new ModelAndView(new RedirectView(getSuccessView()), model);
}

model.put("failure", new Boolean(Boolean.TRUE.booleanValue()));
return new ModelAndView(new RedirectView(getFailureView()), model);
}

/**
* Converts a Date (representing a time) to a String of the form HH:mm
* @param convertDate - Date to convert to a string
* @return a string representation of date of form HH:mm
*/
protected String TimeToString(Date convertDate) {
String timeString = null;
if (convertDate != null) {
Calendar currentCal = new GregorianCalendar();
currentCal.setTime(convertDate);
String hour = new Integer(currentCal.get(Calendar.HOUR_OF_DAY)).toSt ring();
if (hour.length() < 2) {
hour = "0" + hour;
}
String minute = new Integer(currentCal.get(Calendar.MINUTE)).toString( );
if (minute.length() < 2) {
minute = "0" + minute;
}
timeString = hour + ":" + minute;
logger.info("timeString set to " + timeString);
}
return timeString;
}

/**
* Converts a Date to a String of the form dd/mm/yyyy
* @param convertDate - Date to convert to a string
* @return a string representation of date of form dd/mm/yyyy
*/
protected String DateToString(Date convertDate) {
String dateString = null;
if (convertDate != null) {
Calendar currentCal = new GregorianCalendar();
currentCal.setTime(convertDate);
String day = new Integer(currentCal.get(Calendar.DATE)).toString();
if (day.length() < 2) {
day = "0" + day;
}
String month = new Integer(currentCal.get(Calendar.MONTH) + 1).toString();
if (month.length() < 2) {
month = "0" + month;
}
dateString = day + "/" +
month + "/" +
new Integer(currentCal.get(Calendar.YEAR)).toString();
logger.info("dateString set to " + dateString);
}
return dateString;
}

/**
* Method for processing the cancel action of this wizard
* @param request - current HTTP request
* @param response - current HTTP response
* @param command - form object with the current wizard state
* @param errors - validation errors holder
* @return the cancel view
* @throws Exception - in case of invalid state or arguments
*/
protected ModelAndView processCancel(HttpServletRequest request, HttpServletResponse response,
Object command, BindException errors) throws Exception {
// throw new UnsupportedOperationException();
return new ModelAndView(new RedirectView(getFailureView()));
}

public void setJobManager(JobManager jm) {
jobMan = jm;
}

public JobManager getJobManager() {
return jobMan;
}

public void setSuccessView(String successView) {
this.successView = successView;
}

public String getSuccessView() {
return successView;
}

public void setFailureView(String failureView) {
this.failureView = failureView;
}

public String getFailureView() {
return failureView;
}

}



and here are a couple of code snippets from the jsp's

move forward from first page:

<input type="submit" alignment="center" name="_target1" value="<fmt:message key="button.next"/>" />

move back from second page:

<input type="submit" alignment="center" name="_target0" value="<fmt:message key="button.previous"/>">

Alot of the controller will be irrelevant to you but I just put the whole thing up hopefully it is of use to you.

thus
Oct 15th, 2005, 02:14 AM
HTML submit back button moves me forward instead of back as expected.

A quick search on the forum turned up a couple of posts showing similar functionality yet my code does not behave as expected.

I have not overridden any methods in my controller implementation of the AbstractWizardFormController other than processFinal() which works as expected upon completion of my "_finish" page.

I have referred to the Pro Spring book as well as the Java docs and still no luck. Your thoughts would be appreciated.

JSP Page1:



<form action="register.htm?_target1" method="post">
<input type="hidden" name="_page" value="0">
.
.
<input type="submit" value="Continue" name="_target1">
.
</form>


JSP Page2:


<form action="register.htm?_target2" method="post">
<input type="hidden" name="_page" value="1">
.
.
<input type="submit" value="Back" name="_target0">
<input type="submit" value="Continue" name="_target2" >
.
</form>

cerebis
Oct 15th, 2005, 11:05 AM
The Wizard controller is inspecting request parameters and your form is generating two since you have one encoded in the URL and one generated by the form submission. THe controller probably assumes a single occurence, finds the query version first, and promptly executes the respective logic. Drop the _target(N) reference from the actions and it should work.

ie.
Page 1:

<form action="register.htm" method="post">
<input type="hidden" name="_page" value="0">
.
.
<input type="submit" value="Continue" name="_target1">
.
</form>

Page 2

<form action="register.htm" method="post">
<input type="hidden" name="_page" value="1">
.
.
<input type="submit" value="Back" name="_target0">
<input type="submit" value="Continue" name="_target2" >
.
</form>

thus
Oct 15th, 2005, 01:05 PM
You are correct. The _targetN was causing ambiguity in the form submission. Removing it as you suggested solved the problem and it now functions as expected.

cheers :!:

Edward Kenworthy
Nov 9th, 2005, 06:27 AM
addJob.setNoDeparture(new Boolean(Boolean.FALSE.booleanValue()));

What's wrong with "addJob.setNoDeparture(Boolean.False);"?

Even better just use a boolean so "addJob.setNoDeparture(false);" would work?

Sorry I can't help you with your real question: I'm struggling the same as everyone with the arcane intricacies of Spring MVC.

moseph
Mar 29th, 2006, 09:45 PM
<input type="submit" value="Back" name="_target0">
<input type="submit" value="Continue" name="_target2" >

One problem from the above code is that the user can't continue on with the wizard by hitting "enter" on the keyboard... because the first submit value sent is the "back" value and not the "continue". The user would have to mouse click "continue" or tab over to the "continue" button.

Anyone come up with a simple way of getting around this?

peel
Oct 9th, 2006, 12:51 AM
very good job !!! worked here!!!!

peel
Oct 9th, 2006, 12:51 AM
<input type="submit" value="Back" name="_target0">
<input type="submit" value="Continue" name="_target2" >

One problem from the above code is that the user can't continue on with the wizard by hitting "enter" on the keyboard... because the first submit value sent is the "back" value and not the "continue". The user would have to mouse click "continue" or tab over to the "continue" button.

Anyone come up with a simple way of getting around this?

switch the order of the 2 input tag??:rolleyes:

infinity2heaven
Jan 2nd, 2007, 01:43 PM
very useful, works exactly as it says!