Lately I’ve found that Wicket + Ajax == Very nice. More then nice its turns out its just a lot easier to build sites using Ajax and Wicket then it is to do it otherwise. Last night I found myself wanting to place a wizard into an entirely Ajax driven site. Luckily Google pointed me to the answer in this thread: Ajax Wizard Button in Modal Window.
In the spirit of duplicating information all over the internet I’ll paste my copy/paste implementation of the presented solution. It works well!
Step 1: Create the AjaxWizardButton class
-
import org.apache.wicket.ajax.AjaxRequestTarget;
-
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-
import org.apache.wicket.extensions.wizard.IWizard;
-
import org.apache.wicket.extensions.wizard.IWizardModel;
-
import org.apache.wicket.markup.html.form.Form;
-
import org.apache.wicket.model.ResourceModel;
-
-
public abstract class AjaxWizardButton extends AjaxButton {
-
-
private static final long serialVersionUID = 1L;
-
private final IWizard wizard;
-
-
super(id, form);
-
this.setLabel(new ResourceModel(labelResourceKey));
-
this.wizard = wizard;
-
}
-
-
this(id, wizard, null, labelResourceKey);
-
}
-
-
protected final IWizard getWizard() {
-
return wizard;
-
}
-
-
protected final IWizardModel getWizardModel() {
-
return getWizard().getWizardModel();
-
}
-
-
protected final void onSubmit(AjaxRequestTarget target, Form form) {
-
onClick(target, form);
-
}
-
-
protected abstract void onClick(AjaxRequestTarget target, Form form);
-
}
Step 2: Create the buttonbar that will wrap these buttons and override the native buttonbar built into the Wizard.
-
-
-
import org.apache.wicket.ajax.AjaxRequestTarget;
-
import org.apache.wicket.extensions.wizard.IWizardModel;
-
import org.apache.wicket.extensions.wizard.IWizardStep;
-
import org.apache.wicket.extensions.wizard.Wizard;
-
import org.apache.wicket.extensions.wizard.WizardButtonBar;
-
import org.apache.wicket.markup.html.form.Form;
-
-
public class AjaxWizardButtonBar extends WizardButtonBar {
-
-
private static final long serialVersionUID = 1L;
-
-
super(id, wizard);
-
-
addOrReplace(new AjaxWizardButton("next", wizard, "next") {
-
@Override
-
protected void onClick(AjaxRequestTarget target, Form form) {
-
IWizardModel wizardModel = getWizardModel();
-
IWizardStep step = wizardModel.getActiveStep();
-
-
// let the step apply any state
-
step.applyState();
-
-
// if the step completed after applying the state, move the
-
// model onward
-
if (step.isComplete()) {
-
wizardModel.next();
-
} else {
-
error(getLocalizer()
-
.getString(
-
"org.apache.wicket.extensions.wizard.NextButton.step.did.not.complete",
-
this));
-
}
-
-
target.addComponent(wizard);
-
}
-
-
public final boolean isEnabled() {
-
return getWizardModel().isNextAvailable();
-
}
-
});
-
-
addOrReplace(new AjaxWizardButton("previous", wizard, "prev") {
-
-
protected void onClick(AjaxRequestTarget target, Form form) {
-
getWizardModel().previous();
-
target.addComponent(wizard);
-
}
-
-
public final boolean isEnabled() {
-
return getWizardModel().isPreviousAvailable();
-
}
-
});
-
}
-
-
}
-
Step 3: Alter your wizard html markup so you can override the native buttonbar
-
-
<html xmlns:wicket>
-
<wicket:panel>
-
<div>
-
<form wicket:id="form" class="wicketExtensionsWizardForm">
-
-
<span wicket:id="overview"></span>
-
<span wicket:id="header"></span>
-
-
<div wicket:id="view"></div>
-
-
<span wicket:id="feedback"></span>
-
<div class="buttons">
-
<span wicket:id="buttons"></span>
-
</div>
-
</form>
-
</div>
-
</wicket:panel>
-
</html>
-
Step 4: Set your wizard markup output ID so that you can target it with Ajax calls
-
-
theWizard.setOutputMarkupId(true);
-
Step 5: Override the buttonbar call in your wizard class
Step 6: Bask in the glow of warm Ajax.
Pretty simple but the impact is fantastic. Using this code I was able to Ajaxify my wizard in well under 10 minutes.
Thanks Wicket!


I want to quote your post in my blog. It can?
And you et an account on Twitter?
Hi, I’ve followed the above instructions carefully. The problem I have is when a component in one of my classes that extends WizardStep fails the error is not rendered. I get the message:
WARN – WebSession – Component-targetted feedback message was left unrendered. This could be because you are missing a FeedbackPanel on the page. Message: [FeedbackMessage message = [the error message] level = ERROR]
My Wizard HTML matches that which is above and contains the feedback.
Any help would be much appreciated.
Thanks
Can you post you code?