wizard

Description: A multiSelect component. Supports:

  • Inclusion of static or dynamic (contained stages) wizard pages
  • Index and index summary page generation
  • Navigation support with inaccessible pages management
  • Several layouts
  • Acts as a form container, so you can add any inputs directly into it. All pagination buttons act as submit buttons so your data is sent on each page change.
  • Fully stage class control for major business complexity real life occurrences, through the definition attribute in combination with the AbstractWizardStage abstract class.

JavaDoc: Click here

Remarks: There are several possible wizard layouts and functionalities you can chose from. Please check the following examples in this page for a good overview of the major functionalities.\n

The wizard is implemented like an HTML Form. In DIF terms it is implemented as a DIF Form Component with extended functionalities. This means that you should take care with iner forms, since no HTML Forms are allowed within others. For these purposes the Wizard component have the property wrapWithForm that can be set to false. All functionality wizard basic functionalities will remained unchanged, but you will be in charge to create your own form submissions and if desired redirections to the following wizard stages through your own form submit event methods.

Body content: JSP context.

Attributes:

Name Description Data type Required Default value
name The name (identifier) of the wizard String No Generated one in the wizard "wizX" where X is the sequential number of wizards on the current page
title The title of the wizard String No
description The description of the wizard for the index page. String No
showIndex Show index on all pages? Boolean No True if description is set. False otherwise.
showFinish Show the finish buttom? Boolean No True
showCancel Show the cancel buttom? Boolean No True
showExit Show the exit buttom? Boolean No True
showProgress Show the progress information on the bottom? Boolean No True
wrapWithForm If the wizard should render it's inner components inside it's form Boolean No True if no Forms or Grids are contained
readonly Activate readonly mode for all inner fields Boolean No False
indexLayout Index layout. See bellow. String No left
formLayout form layout. See here. String No Pool layout
topNavigator Adds a top navigation to the bottom one. Boolean No False
hasIndexPage Create a automatic wizard index page Boolean No False
height Wizard content fixed height. Forces inner scroll when the content exceeds it Integer No auto
definition The wizard definition object getter method Class Method No if there are no items inside the wizard, "stage.wizardDefinition"
titlePrefix Custom step title prefix text String No
showTitlePrefix Turn On/Off title prefix vizualization Boolean No True
noRequiredIndicator Disable required(*) simbol and required footnote Boolean No False
customMessageIDPrevious The message ID to replace the Previous link text String No previous
customMessageIDNext The message ID to replace the Next link text String No next
customMessageIDCancel The message ID to replace the Cancel link text String No cancel
customMessageIDFinish The message ID to replace the Finish link text String No finish

Index layout values: Available layouts:

  • top: Top index layout. Suitable for indexes with several pages
  • left: Left index layout. Most suited for few pages with small page titles.

Examples:

<dif:document>
    <dif:wizard name="wiz" description="${messages.wizardDescription}" hasIndexPage="true" showIndex="true"
        indexLayout="top" height="300">
        <dif:panel title="${messages.step1Title}" id="panel1" description="${messages.step1Description}">${messages.step1Description}<dif:footnote
                label="${messages.step1Foonote}" />
        </dif:panel>
        <dif:panel title="${messages.step1Title}" id="panel1" description="${messages.step1Description}">${messages.step1Description}</dif:panel>
        <dif:wizardStage stageID="wizardstage2"></dif:wizardStage>
        <dif:panel title="${messages.step2Title}" id="panel2" description="${messages.step2Description}">${messages.step2Description}</dif:panel>
        <dif:panel title="${messages.step3Title}" id="panel3" description="${messages.step3Description}">${messages.step3Description}</dif:panel>
    </dif:wizard>

    <dif:wizard name="wiz2" description="${messages.wizardDescription}" hasIndexPage="true" showIndex="true"
        indexLayout="left" height="300">
        <dif:panel title="${messages.step1Title}" id="panel1" description="${messages.step1Description}">${messages.step1Description}<dif:footnote
                label="${messages.step1Foonote}" />
        </dif:panel>
        <dif:wizardStage stageID="difheader"></dif:wizardStage>
        <dif:panel title="${messages.step2Title}" id="panel2" description="${messages.step2Description}">${messages.step2Description}</dif:panel>
        <dif:panel title="${messages.step3Title}" id="panel3" description="${messages.step3Description}">${messages.step3Description}</dif:panel>
    </dif:wizard>
</dif:document>

Now let's see a more complicated example.

We wan't to have a complex wizard that has a stage for each step for it's intricate interface.
Each submit's it's data to the correct stage as usual. We wan't that all these stages are integrated in a wizard-like fashion and all navigation and flow validation should be automatic.

Each stage should have it's own view like this:

<dif:document>
    <dif:wizard name="wiz definition="${stage.wizardDefinition}" >
        The stage content...
        <dif:comboField autocomplete="true" id="c1">
            <option>First</option>
            <option>Second</option>
            <option>Third</option>
            <option>Forth</option>
        </dif:comboField>
        <dif:dateField id="d1" />
    </dif:wizard>
</dif:document>

If all stages had a common interface we could create a template for all of them to use, or include a common JSP instead. The wizard name on all wizard step stage views must be the same.

We would them create an abstract class for all wizard steps. Like the following:

public abstract class AbstractWizardDemo2 extends AbstractWizardStage {

    /** The stage message list */
    @InjectMessages
    Map<String, String> messages;

    @Override
    protected ViewObject finish(IDIFContext context, int currentStep)
    {
        context.redirectTo("demohome");
        return null;
    }

    /**
     * @see pt.digitalis.dif.presentation.views.jsp.entities.AbstractWizardStage#initializeWizardDefinition(pt.digitalis.dif.presentation.views.jsp.taglibs.objects.WizardDefinition)
     */
    @Override
    protected WizardDefinition initializeWizardDefinition(WizardDefinition def)
    {
        List<WizardStepItem> items = def.getItems();

        for (int i = 1; i <= 3; i++)
            items.add(new WizardStepItem(messages.get("step" + i + "Title"), messages.get("step" + i + "Title"),
                    "wizarddemo2step" + i, true, true, false));

        def.setName("wiz");
        def.setItems(items);
        def.setHasIndexPage(true);
        def.setIndexLayout(WizardDefinition.TOP_INDEX_LAYOUT);

        return def;
    }
}

As you can see, this stage extends the AbstractWizardStage class that processes all validation and navigation of the wizard automatically for us.
You can extend more than these methods to provide behaviors like, specific step validation, or cancel redirection (defaults to the previous breadcrumb), etc.

This class also provides the getter for the EL expression $stage.wizardDefinition, so we need not create it.

The initializeWizardDefinition is where all wizard definitions are indicated. All wizard steps stages defined, and their corresponding stages.

Notice the finish definition also, a simple redirect in this example. Where normally all data entered in all wizard stages would be processed.

Now for each step stage we extend this one, like this:

@StageDefinition(name = "Wizard Demo 2 - Step 1", service = "demoservice")
@View(target = "demos/wizard2step1.jsp")
public class WizardDemo2Step1 extends AbstractWizardDemo2 {

    @Override
    protected ViewObject wizardStepSubmit(IDIFContext context, int currentStep)
    {
        System.out.println("Submited step 1 (real ID = #" + currentStep + ")");
        return null;
    }
}

The only thing we need to provide is the submit method that will process the entered data if available.

See also: * wizardStage component

Back to tag reference