wizard-behavior

Behavior for multi-step forms
108 followers

Wizard Behavoir is an extension that simplifies the handling of multi-step forms.

Features

  • Data persistence
  • Plot-Branching Navigation (PBN)
  • Next/Previous or Forward Only navigation
  • Optional step timeout
  • Invalid step handling
  • All steps submit to the same URL (contoller/action); this greatly simplifies routes
  • Save and recover wizards between sessions
  • Utility methods for use in views to assist navigation

Requirements

Developed using Yii 1.1.6. Should work with all versions

Usage

The Very Brief Version

  • Set up the steps array in the Wizard Behavior configuration
  • Attach Wizard Behavior to a controller
  • Call WizardBehavior's process() method from the desired action
  • Handle the events that WizardBehavior raises

The Long Version

Please see the the manual for full details on using Wizard Behavior - it also fully documents the API and contains example code, and/or download the demo application.

Plot-Branching Navigation (PBN)

PBN allows a wizard to change the path depending on a response from a user. A simple example: you ask the user their gender; you can then take a different path through the wizard presenting gender specific forms depending on their response.

Resources

Credits

Wizard Behavior was inspired by the CakePHP Wizard Component: http://github.com/jaredhoyt

Total 20 comments

#12648 report it
Rodrigo at 2013/04/03 12:22pm
Manual
#11670 report it
opus at 2013/01/25 01:20pm
There's no other place for docs

to julianm. Check the link I provided below. It's not pdf but you can save the html page and use it as it is.

#11669 report it
julianm at 2013/01/25 12:49pm
Missing PDF with Manual

This seems to be a great extension, but unfortunately the links are not working and wizard_behavior_manual.pdf can't be found. Is there any way to re-upload it?

#11666 report it
opus at 2013/01/25 11:19am
Docs for wizard behavior

Here is the link with docs for wizard behavior if anyone needs it.

#11013 report it
tomvdp at 2012/12/10 09:20am
Small error in the demo: here is a fix

If you try to run the demo code, you may encounter an error: "Object not found". It happens when you run a wizard all the way to the end. The completed.php view tries to load the models that it finds in the event steps. But the event step names all start with a lower case character, while the models have an uppercase.

2 possible solutions:
1. In beforeAction of DemoController.php change the event step names to match the model names exactly, or
2. In the view completed.php replace

$model = new $step();

with:

$modelName = ucfirst($step);
$model = new $modelName();
#9486 report it
Wingee at 2012/08/15 12:50pm
Same problem as eclectus

On our dev server it's fine but on the live server in place of the form I get Object id #31. Anybody have any ideas?

#8121 report it
yJeroen at 2012/05/11 05:38pm
Demo?

The demo isnt working at the moment?

#7638 report it
peterdawhiz at 2012/04/04 06:07am
Error on project setup

Other than editing the path to framework folder is there any other configuration. The zipped demo does not run. Gives Object not found error

#7084 report it
mikedilger at 2012/02/23 01:37am
Bugfix for premature exit (during back-and-forth or looping)

Thanks for the great extension.

If you are going back steps and pruning everything in front of you, or if you implement looping over a single step with no steps in front of it, you are going to want to make a change to isValidStep($step) as follows:

protected function isValidStep($step) {
                $index = $this->_steps->indexOf($step);
                if ($index>=0) {
+                       $expectedIndex = $this->_steps->indexOf($this->getExpectedStep());
                        if ($this->forwardOnly)
-                               return $index===$this->_steps->indexOf($this->getExpectedStep());
-                       return $index <= $this->_steps->indexOf($this->getExpectedStep());
+                               return $index===$expectedIndex;
+                       return $expectedIndex>=0 ? $index <= $expectedIndex : $index<=$this->getStepCount();
                }
                return false;
        }

Reasoning: The next expected step is the next step which does not have data. If there are no more steps, and the current step already has data but is being resent (due to going back or looping), the resend would fail. So we say if no further expected step, step is valid as long as it is within range of total steps.

#6445 report it
Sampa at 2012/01/11 04:00am
Tiny note

This is really just a tiny detail but could be annoying if one do not pay attention, in the demo: $config['class']='application.components.WizardBehavior';

in the manual: it says the common place to put the file is in the extentionfolder..

I noticed my mistake early so no time wasted.

#6035 report it
eclectus at 2011/12/07 05:14am
Different server displays 'Object id #32' in place of Form

I was working from your demo Registration wizard, and everything worked fine on our development server. When loading the app to our production server we get 'Object id #32' displayed where the Login Form should be displayed. Everything else displays fine.

Here is the generated page snippet:

<div>Step 1 of 4
  <h3>User</h3>
  <div class="form">Object id #32</div>
</div>
#6021 report it
atrandafir at 2011/12/06 06:57am
Infinite loop on Yii 1.1.3 fixed

On Yii 1.1.3 actions declaration in controller don't allow default arguments, and for some reason WizardBehavior component can't identity the current step value and enters an infinite loop:

Original from the demo:

public function actionSurvey($step=null) {
    $this->pageTitle = 'Survey Wizard';
    $this->process($step);
  }

Edit to make that work:

public function actionSurvey($step=null) {
    $step=isset($_GET['step']) ? $_GET['step'] : null;
    $this->pageTitle = 'Survey Wizard';
    $this->process($step);
  }

Maybe it can be fixed from inside the component in a future update.

Hope it helps someone!

#6020 report it
atrandafir at 2011/12/06 05:57am
Broken link on demo website

Hi,

I just wanted to say I have found a broken link on the demo page: http://wizard-behavior.pbm-webdev.co.uk/

Download The Wizard Behavior and/or the code for this demo: http://www.yiiframework.com/extension/wizard-behaviour/ <- wrong one http://www.yiiframework.com/extension/wizard-behavior/ <- good one

That's it, now I am going to test it because it's just what I need for my forms!! thanks! :)

#5893 report it
Tibor Katelbach at 2011/11/23 05:46am
Javascript submitting

Hi I got the whole wizard going it's great , but I have an interface request where I have to submit the surveys with a link (javascript submit) but this strangely seems to block the process of going to nextStep in some way I don't really understand ? if by any chance someone got it working , I'd love a use case or a sample Cheers

#5259 report it
Yeti at 2011/09/27 07:57am
Repeating the Step?

Have you tried putting the step you want to repeat inside a branch, then repeatedly selecting it using the branch() method?

#5167 report it
russellfeeed at 2011/09/20 03:48pm
Repeating the Step?

I should add - I don't know how many iterations I will need beforehand, so I can't just add more of the same steps to WizardBehaviour::steps.

So my last step in the config is 'getThingForm' and I only have one of those, but need to go back to it programmatically based on an interation count entered in a previous step by the user.

Cheers

Russell

#5166 report it
russellfeeed at 2011/09/20 03:44pm
Repeating the Step?

Thanks Yeti

Good idea about saving into the session using an iteration value. I'll give it a try.

I spent most of this afternoon trying to figure out how to make processStep go back to the same step.

I tried setting WizardBehaviour::handled = false. I tried using $this->process('StepName'). I tried making WizardBehaviour::previousStep() public and using that. I tried $this->redirect()

All failed. Now my head hurts. :-)

Any pointers to how I make it repeat the step?

Thanks Russell

#5165 report it
Yeti at 2011/09/20 03:24pm
Re: Repeat a step

Any ideas how I can make the same step run more than once?

Currently the wizard saves data using the step name as the key, so reusing a step name will just overwrite the data for that step.

The following might be worth trying: (In WizardBehavior)

public function save($data,$step=null,$iteration=null) {
  if (is_int($iteration))
    $this->_session[$this->_stepsKey][(empty($step)?$this->_currentStep:$step)][$iteration] = $data;
  else
    $this->_session[$this->_stepsKey][(empty($step)?$this->_currentStep:$step)] = $data;
}

You would need to track which iteration you are on in the process step handler.

When you retrieve the data at the end of the wizard, repeated steps will have the repetitions as an array.

Let me know if it works - if so I'll add it in to the released version.

#5164 report it
renathy at 2011/09/20 01:31pm
repeating steps

I also need repeating steps several times (i need cycling), but in the following way:

1) Step1 2) Step2 3) Step3 4) Ste[4 -> finish or go to step2 again I need repeating step2-step4 till user decides to finish.

#5161 report it
russellfeeed at 2011/09/20 12:21pm
Repeat a step

Hi

I need to repeat step several times.

Here's my example:

  1. How many things do you want to create? [.....] < e.g. user enters 5
  2. Enter the name of your thing (1 of 5) [.......]
  3. Enter the name of your thing (2 of 5) [......]
  4. Enter the name of your thing (3 of 5) [......]
  5. Enter the name of your thing (4 of 5) [......]
  6. Enter the name of your thing (5 of 5) [.....]

I've tried this in my processStep handler:

case 'getThingCountForm':
    // Save a shadow so we can count down and loop
    $model->thingcountdown = $model->thingcount;
    $event->sender->save($model->attributes);   
    break;
 
case 'getThingForm':
        // save the new Thing
        $thing = new Thing();
        $thing->name = $model->thingname;
        $thing->save();                 
 
        // Decrement the countdown
        $stepdata = $event->sender->read();
        $stepdata ['getThingCountForm']['thingcountdown']--;        
        $event->sender->save($stepdata ['getThingCountForm'],'getThingCountForm');
 
        if ($stepdata ['getThingCountForm']['thingcountdown']>0) {
            $event->handled = false;                    
            $this->redirect(array('survey','step'=>'getThingForm'),false);
        }
        break;

Any ideas how I can make the same step run more than once?

thanks in advance

Russell

Leave a comment

Please to leave your comment.

Create extension