Yii 1.1: wizard-behavior

Behavior for multi-step forms
114 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

#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

With

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

@heal

"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:
'elements'=>array(
                'test'=>array('htmlOptions'=>array('hint'=>'myhint')),
                'type'=>array(
                    'type'=>'dropdownlist',
                    'data'=>$this->getPackageList(),
                ),
            ),
#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(
            'elements'=>array(
                'title'=>['hint'=>'my hint'],
                'last_name'=>['hint'=>'my hint'],
                'first_name'=>[],
            ),
            'buttons'=>array(
                'submit'=>array(
                    'type'=>'submit',
                    'label'=>'Next'
                ),
            ),
        ), $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;".

Fix:

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]));
                    else
                        $parsed[$label] = $step[$branch];
                }
            }
            else
                $parsed[$label] = $step;
        }
        return $parsed;
    }
#14199 report it
lahiponeja at 2013/07/25 04:05pm
@eclectus

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

serialize($data);

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
            Yii::log(json_encode($event->data),'error');
            $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'];
            $player->save();

Hope this helps.

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

Hi,

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
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! :)

Leave a comment

Please to leave your comment.

Create extension