Panel | ||||
---|---|---|---|---|
| ||||
|
Note
Since Wicket 1.2 RC4, there is a wizard component in wicket-extensions. Examples
of using this can be found in wicket-examples/wizard.
Copied from the mailinglist
There are generally two ways of doing this (I think):
...
Another thing that might be a good idea, is to use command patterns for navigation actions. For example, I use this for a project:
Panel | |
---|---|
Code Block | |
public interface INavigationAction
{
void navigate(RequestCycle requestCycle);
}
| |
Panel | |
Wiki Markup |
/* action to navigate back to this page. */
private final INavigationAction backToThisPageNavigationAction = new INavigationAction()
{
public void navigate(RequestCycle requestCycle)
{
requestCycle.setResponsePage(VenueListPage.this);
}
}
|
and then have something like:
Code Block | |
---|---|
Panel | |
Wiki Markup |
public VenueDetailsPage(Long venueId, INavigationAction backNavigationAction)
{
...
add(new Link("cancelButton")
{
public void onClick()
{
backNavigationAction.navigate(getRequestCycle());
}
});
...
|
Anyway, that's just an idea. You might come up with a more elegant pattern, or you might be happy with a tight coupling between the wizard steps.
...
First, why this way of implementing wizard is better than page-oriented style. When you post to an adress1address1, then redirect to address2 and then display a view, most browsers do not add address2 to history list again and again (save for Opera). Therefore, it is impossible to access old wizard page simply by clicking browser's "Back" button. Also, because all views correspond to one address, it is impossible to navigate directly to a certain wizard page; it is only possible to navigate to the wizard as a whole. This approach simplifies navigation, error handling and makes wizard more robust.
...
WizardPage class is a main page of this sample. It creates wizard controller and steps/panels.
Code Block |
---|
{panel} public class WizardPage extends WicketExamplePage { {panel} {panel} protected static Log log = LogFactory.getLog(WicketExamplePage.class); {panel} {panel} LoginWizard wizard; {panel} {panel} // Array of wizard panels WizardPanel[] wizardPanels = new WizardPanel[2]; {panel} {panel} /** * Constructor */ public WizardPage() { setVersioned(false); WizardFormInputModelSignup rawModel = new WizardFormInputModelSignup(); IModel wizardModel = new CompoundPropertyModel(rawModel); {panel} {panel} // Each panel is a wizard step. Initialization in the loop cannot // be used, because each step defines different model-related methods, // thus all steps have different types. wizardPanels[LoginWizard.STEP_SIGNUP] = new WizardPanelSignup("wp"+LoginWizard.STEP_SIGNUP, wizardModel, this); wizardPanels[LoginWizard.STEP_CONFIRM] = new WizardPanelConfirm("wp"+LoginWizard.STEP_CONFIRM, wizardModel, this); {panel} {panel} wizard = new LoginWizard(rawModel, wizardPanels); {panel} {panel} // Add all panels to wizard page for (int i = 0; i < wizardPanels.length; i++) { add(wizardPanels[i]); } updatePanels(); } {panel} {panel} public void onCancel() { wizard = null; updatePanels(); } {panel} {panel} public boolean onBack() { boolean movedBack = false; if (wizard != null) { movedBack = wizard.back(); } updatePanels(); return movedBack; } {panel} {panel} public boolean onNext() { boolean movedNext = false; if (wizard != null) { movedNext = wizard.forward(); } updatePanels(); return movedNext; } {panel} {panel} /** * Hide all panels except one that corresponds to current wizard step. * If wizard is not active or is disposed, then all panels are hidden. */ public void updatePanels() { for (int i = 0; i < wizardPanels.length; i++) { wizardPanels[i].setVisible( wizard != null && ("wp"+i).equals(wizard.getCurrentStepName()) ); } } } {panel} |
The wizard controller is defined in LoginWizard class. It defines the transition from Signup step to Confirm step:
Code Block |
---|
{panel} wizardSteps[STEP_SIGNUP].addOutgoingTransition( new WizardTransition(this, "Login To Confirm", wizardSteps[STEP_CONFIRM]) { public boolean validate() { LoginWizard wizard = (LoginWizard)this.getWizard(); WizardFormInputModelSignup model = wizard.getModel(); return model.isValidNameAndPassword(); } } ); {panel} |
If validate method of this transition returns true, then wizard moves from signup to confirm step, otherwize it stays on the current step, which is signup step in our case.
...