Build a Dynamic Wizard with Oracle JET

by Kenneth Lange  

In my last post about Oracle JET, we looked at how you can create a simple web app on top of a REST service.

That’s a good start, but it didn’t show how flexible Oracle JET’s user interface really is, so let’s create a highly configurable wizard to show its flexibility.

The Wizard Demo App

The wizard is made up of a number of steps, and each step can have a number of questions:

The idea is that the steps and questions shouldn’t be hardcoded in the UI, but instead be generated from metadata.

Configure the Wizard

We store the metadata in a simple JavaScript object:

// Initialize the wizard with sample questions.
this.data = {
  name:"Create Customer",
  steps:[
    {
      id:"0",
      name:"Basic Information",
      questions: [
        {id:"0", type:"Text", question:"Full name",   answer:""},
        {id:"1", type:"Text", question:"Email",       answer:""},
        {id:"2", type:"YesNo",question:"VIP Customer",answer:""}
      ]
    },
    {
      id:"1",
      name:"Additional Information",
      questions:[
        {id:"3", type:"YesNo",question:"Receive newsletter?",answer:""},
        {id:"4", type:"YesNo",question:"Discount?",          answer:""}
      ]
    },
    {
      id:"2",
      name:"Confirmation",
      questions:[
        {id:"5", type:"YesNo",question:"Are all entered data correct?",answer:""}
      ]
    }
  ]
};

As you can see, the name of the wizard is “Create Customer”, it’s made up of 3 steps (“Basic Information”, “Additional Information” and “Confirmation”) and each step contains a number of questions.

When you add/remove steps and questions in the JavaScript object, the UI should automatically reflect the new setup without you having to change any code.

In a real app you would probably get the metadata from a REST service, and provide a nice UI where a business user can adjust the metadata to his or her needs. But this has been left out to keep the demo code nice and small.

Generate the Wizard’s UI based on Metadata

We use Oracle JET’s train component to show the user all the steps in the wizard:

<div id="train"
     class="oj-train-stretch"
     data-bind="ojComponent: {component: "ojTrain",
  		              selected: currentStepNo,
  		              steps: trainSteps,
                              select: function() {go(currentStepNo());}}">
</div>

The trainSteps array has name-value pairs that contains the steps. We use a small loop that creates the array based on the metadata:

// Make an array of steps for the Oracle JET train component.    
for(i=0; i < this.data.steps.length; i++) {
  this.trainSteps.push({id:   this.data.steps[i].id,
                        label:this.data.steps[i].name});
}

The questions inside a step are generated using Knockout bindings:

<!-- Displays the questions -->
<div data-bind="foreach: questions">

  <!-- Text Question -->
  <div data-bind="if: type == 'Text'">
    <label data-bind="attr: {for: id}, text: question">
    <input type="text" data-bind="attr: {id: id}, ojComponent: {component: 'ojInputText', value: answer}"/>
  </div>

  <!-- YesNo Question -->
  <div data-bind="if: type == 'YesNo'">
    <label data-bind="attr: {for: id}, text: question">
    <select data-bind="attr: {id: id}, ojComponent: {component: 'ojSelect', value: answer}">
      <option value="Yes">Yes
      <option value="No">No
    </select>
  </div>
</div>

Basically, the foreach binding loops through all the questions, and then use the if binding to check what type the question is, and then generates the right HTML for that question type.

In this example, there are only two question types, but it could easily be extended with many more types. Even advanced types such as maps. Basically, anything as long as you can store the result in the answer variable.

If you want to play around with the example, feel free to download the code.

Share this post:


Subscribe to this blog:

Just enter your email below and press the button:


Related Posts: