Yii 1.1: wizard-behavior

Behavior for multi-step forms

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


  • 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


Developed using Yii 1.1.6. Should work with all versions


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.



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

Total 20 comments

#18230 report it
eclectus at 2014/09/30 04:27pm
Saving incomplete forms


Not sure what you are having a problem with, but maybe this can help: (1) you can save using Ajax without having to go out of the wizard "cycle". (2) you can always call save() when a step is complete before moving to the next step. (3) the wizard saves the filled data into the model, so you really do not lose any of the data while you are still within the wizard so you can go back and forth - i.e. show a "missing fields" dynamic step at the end asking to complete the missing fields, no need to save until the user submits the validated form.

#18222 report it
oceanscrashing at 2014/09/29 10:40am
Saving incomplete forms, or saving on the last page

This extension is great, and I think I can find about 1000 ways to integrate it into my workflow.

I've got a problem currently in use that I think is a simple one to fix, I'm just not quite grasping how to approach it:

Say I've got a three page form, and I'm on the last page. I realize that I don't have all the information needed to complete the last page. I'd like to save my progress, but I can't save without all the required fields entered. If I fill the fields with temporary information and hit save, the form is submitted instead of saved.

How can a form be saved without being submitted on the last page? I think that if you suspend validation until the full form is submitted, you'd hit an issue where page x of an x page form had an error, and you'd need to redirect a user to that page of the form. Any advice would be greatly appreciated. I've taken a few swings at this issue, but I think a fresh set of eyes might be able to see what I'm missing easily.

#15545 report it
Nisanth thulasi at 2013/11/20 05:46am
demo navigation

I have replaced the line, in view/demo.php

<a href="/demo/registration">Registration Wizard&nbsp;&raquo;</a>Registration


<a href="<?php echo $this->createUrl('/demo/registration'); ?>">Registration
#15253 report it
Siquo at 2013/10/21 05:25am
Wizardbehaviour and TbForm


"Don't works" is a bit of a vague error message. TbForm should work kind of similar to CForm. Depending on your error you can try/check:

  • use array() notation instead of []
  • Yii::import('ext.bootstrap.form.*');
  • Make sure the attribute with that name exists
  • Make sure a "rules" entry for that attribute exists
  • In case of dropdown elements, don't use "items" but "data" to keep the option list.
  • Make sure the "hint" is actually inside a htmlOptions array:
#15232 report it
heal at 2013/10/20 05:46am
How to use TbForm with this extension?

Hello! Thanks for this great extension. Can I ask an advice about using Yii Bootstrap (TbForm) forms with the wizard? This don't works:

public function getForm() {
        return new TbForm(array(
                'title'=>['hint'=>'my hint'],
                'last_name'=>['hint'=>'my hint'],
        ), $this);

Thank you!

#15041 report it
Siquo at 2013/10/01 05:04am
Bugfix for maintaining step order with labelless trees

If you don't use labels, and try to insert a branch, the order gets screwed because the original order-integer is used as a label index at "$parsed[$label] = $step;".


private function _parseSteps($steps) {
        $parsed = array();
        foreach ($steps as $label=>$step) {
            $branch = '';
+           if(is_numeric($label))
+               $label = $step;
            if (is_array($step)) {
                foreach (array_keys($step) as $branchName) {
                    $branchDirective = $this->branchDirective($branchName);
                    if (
                        ($branchDirective && $branchDirective===self::BRANCH_SELECT) ||
                        (empty($branch) && $this->defaultBranch)
                        $branch = $branchName;
                if (!empty($branch)) {
                    if (is_array($step[$branch]))
                        $parsed = array_merge($parsed, $this->_parseSteps($step[$branch]));
                        $parsed[$label] = $step[$branch];
                $parsed[$label] = $step;
        return $parsed;
#14199 report it
lahiponeja at 2013/07/25 04:05pm

Thanks, Your information was very helpful. :)

#14174 report it
eclectus at 2013/07/24 11:45am
Reply to @lahiponeja

A crude example, if you don't want to simply use


can be done like this inside your controller where you run the wizard, assuming you have a Player model:

public function wizardFinished($event) {
        if ($event->step===true) {
            //save data to database
            $player = new Player();
            $player->fname = $event->data['playerInfo']['fname'];
            $player->lname = $event->data['playerInfo']['lname'];
            $player->addr = $event->data['playerInfo']['addr'];
            $player->city = $event->data['playerInfo']['city'];
            $player->state = $event->data['playerInfo']['state'];
            $player->cntry = $event->data['playerInfo']['cntry'];
            $player->zip = $event->data['playerInfo']['zip'];
            $player->phone = $event->data['playerInfo']['phone'];
            $player->email = $event->data['playerLogin']['email'];
            $player->pwd = $event->data['playerLogin']['pwd'];

Hope this helps.

#14172 report it
lahiponeja at 2013/07/24 10:52am
How to save model in BD?


Anybody can help me please?...my question is this:

My behavior working ok, but I don´t know, how to save the information content in $event->data because this variable is an array associative.

thanks for tell me any idea, for this problem.

#12648 report it
Rodrigo at 2013/04/03 12:22pm
#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();


$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

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
  <div class="form">Object id #32</div>

Leave a comment

Please to leave your comment.

Create extension