Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Panel
borderStylesolid
titleTable of contents
Table of Contents
minLevel1

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:

unmigrated-wiki-markup

  /* action to navigate back to this page. */
  private final INavigationAction backToThisPageNavigationAction = new INavigationAction()
  {
     public void navigate(RequestCycle requestCycle)
     {
        requestCycle.setResponsePage(VenueListPage.this);
     }
  }
Panel
Code Block

  public interface INavigationAction
  {
     void navigate(RequestCycle requestCycle);
  }
Panel
Wiki Markup

and then have something like:


   public VenueDetailsPage(Long venueId, INavigationAction backNavigationAction)
   {
      ...
      add(new Link("cancelButton")
      {
         public void onClick()
         {
            backNavigationAction.navigate(getRequestCycle());
         }
      });
      ...
Code Block
Panel
Wiki Markup

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.

...