Wicket and magical stuff

So you want Wicket to do more magical stuff for you? Great, because I just added a wizard component to the wicket-extensions.

Wicket wizard

You probably already know, but for the sake of clarity: a wizard component is a dialog component that takes it's users through a number of predefined steps. It has common functionality like a next, previous, finish and cancel button, and it uses a transition rules to let clients navigate through it's steps.

The standard implementation of the wizard component is wicket.extensions.wizard.Wizard, and the interface that abstract what the wizard does/ could do is wicket.extensions.wizard.IWizardModel. This model knows what the current step of the wizard is, and knows what transitions are available – handy for turning buttons on and off – and how these transitions should be made (or how to delegate them). A single step in a wizard is defined in interface wicket.extensions.wizard.IWizardStep and it's default panel based implementation wicket.extensions.wizard.WizardStep. Wizard steps are responsible for managing their state (quite natural, as they are just objects like everything is with Wicket), and deliver the header and main content components (typically panels or fragments).

There is an example in wicket-examples that shows a basic use of the wizard. It shows two not-so-useful static wizards and one form based wizard. If you look at the NewUserWizard example, you can see this in it's constructor:

user = new User();
setModel(new CompoundPropertyModel(this));
WizardModel model = new WizardModel();
model.add(new UserNameStep());
model.add(new UserDetailsStep());
model.add(new UserRolesStep());
model.add(new ConfirmationStep());
init(model);

This is how a wizard and it's model gets configured. A new default wizard model is created, the steps are added in the sequence that they will be executed. An interesting note here – not visible from this code fragment, is that the UserRolesStep is an optional step. The condition is encoded as part of the step itself, but you can also externalize the condition if you prefer that.

Here is what a step looks like (the user name step, of which a screen shot is displayed above).

private final class UserNameStep extends WizardStep {

public UserNameStep() {
    super(new ResourceModel("username.title"), new ResourceModel("username.summary"));
        add(new RequiredTextField("user.userName"));
        add(new RequiredTextField("user.email")
            .add(EmailAddressPatternValidator.getInstance()));
    }
  }
}

The two resource models are for the header component, and will return the localized labels for the title and summary, and the two text fields will work on the parents's CompoundPropertyModel (note that using a required textfield is just short hand for using a text field and setting the required property to true).

The markup of that step looks like this (NewUserWizard$UserNameStep.html):

<wicket:panel>
 <table>
  <tbody>
   <tr>
    <td><wicket:message key="username">Username</wicket:message></td>
    <td><input wicket:id="user.userName" type="text" /></td>
   </tr>
   <tr>
    <td><wicket:message key="email">Email Adress</wicket:message></td>
    <td><input wicket:id="user.email" type="text" /></td>
   </tr>
  </tbody>
 </table>
</wicket:panel>

If your reaction to seeing this is: 'hey, but that's not magical enough for me', do something creative and create a nice useful base step for your case. For example, a panel that analyzes the object (model?) you give it, and based on that creates a dynamic form. Or render an xform definition. The wizard package provide you with a basic working model, and some convenience classes, and the rest is up to you. We wouldn't want to spoil all the programming for you ;).

Check the wizard out in the next release. Hope you'll find it useful.

About these ads

2 thoughts on “Wicket and magical stuff

  1. nice. how to change locale/label for buttons?

  2. Anirban says:

    Hi, I am using the Wizard extension and facing a problem.It seems the markup for the wizard steps are not loading. Can you give some clues/pointers to find out where i am going wrong.

    i have named the wizard step pages as WizardClassname$WizardStepName.html

    with empty steps a blank wizard is displayed with 3 steps. As soon as i am adding components to a step i get this exception:

    ——
    The component(s) below failed to render. A common problem is that you have added a component in code but forgot to reference it in the markup (thus the component will never be rendered).

    1. [Component id = simple]
    —–
    The step markup and Step classes are in sync.

    Thanks

Comments are closed.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: