Wizard Behavior

This is an awesome extension, Thank you!

I have a question regarding visible items in the steps (after scouring the net and reading all the threads)… so here goes…

I need to add the current users ID (Yii::app()->user->id) to the final output. I can do this, but then the value is shown. The minute I try “hide” or set it’s visible property to false, it’s not included in the array.

Here’s a snippet of the model code in step 1:





class Wizard_step1 extends CFormModel {

	public $user_id;

	public $turnover;


	public function rules() {

		return array

		(

			array('user_id, turnover', 'safe'),

		);

	}


	public function getForm() {

		

		$te = Yii::app()->user->id;

		

		return new CForm(array(

			'showErrorSummary'=>true,

			'elements'=>array(

				'user_id'=>array

				(

					'type'=>'text',

					'value'=>$te,

				),

				'turnover'=>array

				(

					'type'=>'dropdownlist',

					'items'=>array

					(,

						''=>'',    //this forces validation to check for a value, i.e. value in dropdown box not selected... won't continue to next step (for those that want this functionality <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/smile.gif' class='bbc_emoticon' alt=':)' />

						'2'=>'R0m - R1.5m',

						'3'=>'R1.5m - R2.5m',

						'4'=>'R2.5m - R5m',

						'5'=>'R5m - R11.5m',

						'6'=>'R11.5m - R15m',

					)

				),



what can I do in order to set this so that the user_id is not visible to the user, but will still be added to array data at completion of all the steps? Maybe I’m doing it completely wrong and the data needs to be added elsewhere in the program? any assistance will be great!

Regards,

G

Demo page broken. :(

Did u find any solution to ur post? pliz help me, am also stuck

demay

The demo page is still offline… any chance it could be put back online?

Great extension. Quick question – When clicking on a "previous" button, a wizard page looks like it will lose any entered data by a user. Not sure if this is by design, but is there a way that the form can retain state when clicking on "previous" buttons?

Thanks.

Couldn’t get to demo or documentation page online (is it just me?)

… but I did manage to view demo app by downloading, installing (and tweaking) locally. Looks great!

Only thing missing fo me is the Documentation (Wizard_Behaviour_Manual.pdf), which is not in the list of available Downloads.

Any chance of adding it there?

Thanks

Here is the link www.scribd.com/fullscreen/110910020?access_key=key-yo2a3actxxs16pkkob1 where you can find docs

The issue reported in the reply #36 of this topic about the PBN skipping steps, seems a bug to me, the patch on ‘WizardBehaviour::_parseSteps($steps)’ suggested by Say_Ten works perfectly:




@WizardBehaviour.php Line:556 

-				$parsed[$label] = $step;

+				$parsed[] = $step;



Hi, As Joblo says before…

"

What’s the easiest way to display input results from previous steps to the user when he is working on a step?

How can I access the results of the previous steps?

For example - registration wizard demo:

I want to display the username / email from step1 at the top of the step2 form (Profile), and also on step3 …

"

I ask the same question, because, WizardBehavior::read($step) works fine in wizardProcessStep, but does not works in Form Builder (model level). How to access variables values choosen in previous step.

eg in form builder:

if step1.myoption equals 1 then

enable form element A

else if step1.myoption equals 2 then

enable form element B

else

enable default form element

endif

This is my first question and, thanks in advance.

Hi,

i want make static menubar for this i wrote this code :

	&lt;?php  &#036;this-&gt;widget('zii.widgets.CMenu',array(


	


		'items'=&gt;array(


			array('label'=&gt;'Home', 'url'=&gt;array('/site/index')),


			


			 


			


			array('label'=&gt;'Company', 'url'=&gt;'#'


			'items'=&gt;array(


							array('label'=&gt;'About Us', 


													'items'=&gt;array(


																	array('label'=&gt;'Our Story', 'url'=&gt;'#'),							


																	array('label'=&gt;'Our Differance', 'url'=&gt;'#'),


																	array('label'=&gt;'Our Working Methedology', 'url'=&gt;'#'),


																	)),							


							array('label'=&gt;'Client', 


													'items'=&gt;array(


																	array('label'=&gt;'Testimonial', 'url'=&gt;'#'),							


																	array('label'=&gt;'Client Vedio Testimonial', 'url'=&gt;'#'),


																	)),


							)),


    		array('label'=&gt;'Services', 'url'=&gt;'#'


			 'items'=&gt;array(


							array('label'=&gt;'Moblie Application', 


													'items'=&gt;array(


																	array('label'=&gt;'IPhone App Development', 'url'=&gt;'#'),							


																	array('label'=&gt;'IPad App Development', 'url'=&gt;'#'),


																	array('label'=&gt;'Android App Development', 'url'=&gt;'#'),


																	array('label'=&gt;'Windows Moblie Development', 'url'=&gt;'#'),


																	array('label'=&gt;'Cross-Platform Development', 'url'=&gt;'#'),


																   )),


							array('label'=&gt;'Web Development', 


													'items'=&gt;array(


																	array('label'=&gt;'Mobile App Web Development', 'url'=&gt;'#'),							


																	array('label'=&gt;'Web Application Development', 'url'=&gt;'#'),


																	array('label'=&gt;'Web Design And Development', 'url'=&gt;'#'),


																	array('label'=&gt;'E-Commerce Web Development', 'url'=&gt;'#'),


																	array('label'=&gt;'CMS Website Development', 'url'=&gt;'#'),


																    )),


							)),


			array('label'=&gt;'Solutions', 'url'=&gt;'#'


			'items'=&gt;array(


							array('label'=&gt;'Technology', 


														'items'=&gt;array(


																	array('label'=&gt;'PHP Development', 'url'=&gt;'#'),							


																	array('label'=&gt;'Open Source Development', 'url'=&gt;'#'),


																	array('label'=&gt;'Microsoft Technology Development', 'url'=&gt;'#'),


																	)),


							array('label'=&gt;'Staffing', 


														'items'=&gt;array(


																	array('label'=&gt;'Hire IPhone App Developer', 'url'=&gt;'#'),							


																	array('label'=&gt;'Hire IPad App Developer', 'url'=&gt;'#'),


																	array('label'=&gt;'Hire Android App Developer', 'url'=&gt;'#'),


																	array('label'=&gt;'Hire PHP Developer', 'url'=&gt;'#'),


																	array('label'=&gt;'Hire HTML5 Developer', 'url'=&gt;'#'),


																   )),


						)),


			array('label'=&gt;'Portfolio', 'url'=&gt;array('/site/visitors')),


			array('label'=&gt;'Case Studies', 'url'=&gt;array('/site/visitors')),


			array('label'=&gt;'Get A Quote', 'url'=&gt;array('/site/visitors')),


			array('label'=&gt;'Login', 'url'=&gt;array('/site/login'), 'visible'=&gt;Yii::app()-&gt;user-&gt;isGuest),


			array('label'=&gt;'Logout ('.Yii::app()-&gt;user-&gt;name.')', 'url'=&gt;array('/site/logout'), 'visible'=&gt;&#33;Yii::app()-&gt;user-&gt;isGuest)


		),


		


	)); 

but it can’t work well and give a parse error like :

Parse error: syntax error, unexpected ‘‘items’’ (T_CONSTANT_ENCAPSED_STRING), expecting ‘)’ in C:\xampp\htdocs\mayur\demoapp\protected\views\layouts\main.php on line 41.

please give me solution for this error.

give me replay as soon as you can…

thank you.

Im used WizardBehavior::read($step) in step #2 (named ‘ChooseQuestions’) trying to

read previous step named ‘InitParams’:

WizardBehavior::read(‘InitParams’);

So, get the error:

CException

Property "ChooseQuestions._stepsKey" is not defined.

/var/www/hnc/protected/extensions/wb/WizardBehavior.php(279)

267 public function save($data,$step=null) {

268 $this->_session[$this->_stepsKey][(empty($step)?$this->_currentStep:$step)] = $data;

269 }

270

271 /**

272 * Reads data stored for a step.

273 * @param string The name of the step. If empty the data for all steps are returned.

274 * @return mixed Data for the specified step; array: data for all steps; null is no data exist for the specified step.

275 */

276 public function read($step=null) {

277 return (empty($step)?

278 $this->_session[$this->_stepsKey]->toArray():

279 $this->_session[$this->_stepsKey][$step]

etc.

What I do wrong?

Code related to wizard-behavior:




public function beforeAction($action) {

	$config = array(

		'class' => 'application.components.WizardBehavior',

		'steps' => array('step1', 'step2', 'step3')

	);

	$this->attachBehavior('wizard', $config);

	return parent::beforeAction($action);

}


public function actionWizard($step=null) {

	$this->process($step);

}


public function wizardStart($event) {

	$event->handled = true;

}


public function wizardProcessStep($event) {

	$name = 'process'.ucfirst($event->step);

	if (method_exists($this, $name))

		$event->handled = call_user_func(array($this,$name), $event);

	else

		throw new CException(Yii::t('yii','{class} does not have a method named "{name}".', array('{class}'=>get_class($this), '{name}'=>$name)));

}


public function processStep1($event) {		

	$model=new Card;

	

	// TODO $event->data is always empty

	if($event->data) {

		$model->attributes = $event->data;

		$model->image = CUploadedFile::getInstance($model, 'image');

		$model->texture = "";

	}

	

	// TODO if true, then next step is still not loaded, tested with $_POST instead of $event->data

	if($event->data && $model->validate()) {

		$event->sender->save($model->attributes);

		$event->handled = true;

	} else {

		$this->render('create',array(

			'model'=>$model,

			'event' => $event

		));

	}

}


public function processStep2($event) {

	// TODO Render editor

}


public function processStep3($event) {

	$model=new Card;

	

	if($event->data) {

		$model->attributes = $event->data;

		if($model->save()) {

			$model->image->saveAs('uploads/' . time() . "." . $model->image->extensionName);

			$this->redirect(array('view','id'=>$model->id));

		}

	}

	

	// TODO Render preview

}



My problems:

  • $event->data is always empty in processStep*

  • When validate() == true the next step does not load

I’m modifying my code from actionCreate to use in the wizard. The form is a TbActiveForm view, not an CForm coded in the model as done in the examples.

Tips, suggestions and help are very welcome!

Hi Phim

I don’t know it you’ve been able to sort out the problems you were having:

$event->data is always empty in processStep*

$event->data is always empty until the form in that step has been submitted and the data has been successfully validated.

When validate() == true the next step does not load


public function processStep1($event) {          

        $model=new Card;

        

        // TODO $event->data is always empty

        if($event->data) {

                $model->attributes = $event->data;

                $model->image = CUploadedFile::getInstance($model, 'image');

                $model->texture = "";

        }

        

        // TODO if true, then next step is still not loaded, tested with $_POST instead of $event->data

        if($event->data && $model->validate()) {

                $event->sender->save($model->attributes);

                $event->handled = true;

        } else {

                $this->render('create',array(

                        'model'=>$model,

                        'event' => $event

                ));

        }

}

Where you have


if($event->data && $model->validate())

remove $event->data as it will cause that conditional statement to always return false. It is only after $event->sender->save($model->attributes) executes that there’ll be data in $event->data. So while validate()==true $event->data will always be false because $event->sender->save will never execute.

To move to the next step, in your code, after $data->handled=true, add


return true;

It seems that, without that line, wizardProcessStep doesn’t move to the next step.

Hope that helps

Hi all,

Just wondering if it is possible to make dropdown menus in Wizard Behavior.

for example, I have the following code from for my Address model:




public function getForm() {

        return new CForm(array(

            'showErrorSummary'=>true,

            'elements'=>array(

                'street'=>array(),

                'city'=>array(),

                'state'=>array(),

                'zipcode'=>array(),

                'country'=>array(),

            ),

            'buttons'=>array(

                'submit'=>array(

                    'type'=>'submit',

                    'label'=>'Next'

                ),

                'save_draft'=>array(

                    'type'=>'submit',

                    'label'=>'Save'

                )

            )

        ), $this);

    }



I’d like country to be a dropdown menu populated with countries from the Country table instead of a text input.

Currently I have it set up so that if the user has already completed that step, the text fields are autofilled.

So in the Country field, the id of country appears, for example ‘US’. I’d like it so that the user’s country is preselected in this case.

I’ve been searching around, but cannot find anything specific to Wizard Behavior.

Any help would be appreciated.

Regards

Phil

Hi again,

After sleeping on it, I fixed it.

Very simple in the end too! :slight_smile:




'country'=>array(

           'type'=>'dropdownlist',

           'prompt'=>'Select Country',

           'items'=>CHtml::listData(Country::model()->findAll(), 'id', 'country_name'),

           ),



Cheers

Phil

Nope, this may break steps with actual labels set. Try this more conservative one instead:




if ( isset($parsed[$label]) ) {

  	$parsed[] = $step; //add the step at the end if it already exists

}

else {

	$parsed[$label] = $step;

}



The extension really needs to be updated, this is a serious bug, especially if the intention was to allow two identical names for steps…

Hi guys

Just wondering if it is possible to insert multiple records to a model in a step. For example, in my app, a student is applying for courses and can apply for two courses. Of those courses, the student can select a 1st priority (required) and 2nd priority. So if the student wants to study 2 courses, they can effectively put 4 rows into the database as there could be two 1st priority and two 2nd priority courses. I have the wizard set up so that each step inserts directly to the database so that the user can login again and continue. My problem is, I can only display one dropdown list of courses at a time through the following code in my model:




public function getForm() {

        return new CForm(array(

            'showErrorSummary'=>true,

            'elements'=>array(

                'course'=>array(

                    'label'=>'1st Priority',

                    'type'=>'dropdownlist',

                    'prompt'=>'Select 1st Priority Course',

                    'items'=>CHtml::listData(Course::model()->findAll(), 'course_id', 'course_name'),

                ),

            ),

            'buttons'=>array(

                'previous'=>array(

                    'type'=>'submit',

                    'label'=>'Previous'

                ),

                'submit'=>array(

                    'type'=>'submit',

                    'label'=>'Next'

                )

            )

        ), $this);

    }



I’m sure that I could use branching to ask the user if they want to select a 2nd priority and then ask them if they want to choose another course etc, but what I’d like to do, in order to minimize branching, is to allow them to choose their 1st and 2nd priority courses on the same page and then check a checkbox to branch to a second course choice (with 1st and 2nd priorities).

So basically, how can I have two dropdown lists with 1st priority and 2nd priority courses so that if courses from both dropdowns are selected, two records are inserted when the user clicks next.

Any help would be most appreciated!!

Hello, I’m trying to use the wizard with yii-booster extension, but I can’t render the TbForm.

in controller I have this:




public function wizardProcessStep($event) { 

        $modelName = ucfirst($event->step); 

        $model = new $modelName('scenario'); 

        $model->attributes = $event->data;

        

        $form = $model->getForm();


        if ($form->submitted() && $form->validate()) { 

            $event->sender->save($model->attributes); 

            $event->handled = true;

        } else {

            $this->render('form', compact('event','form'), false);

        }

    }



model:




<?php

class Person extends CFormModel

{

    public $title;

    public $last_name; //priezvisko

    public $first_name; //meno

    //...

    

	public function rules()

	{

        return array(

            ['last_name, first_name, personal_number, street, house_number, postal_code, town, country', 'required'],

	    ['title', 'length', 'max'=>9],

            //...

            );

	}


    //this is the TbForm, I can't render it. 

    public function getForm() {

        return TbForm::createForm(array(

            'elements'=>array(

                'title'=>['hint'=>'my hint'],

                'last_name'=>['hint'=>'my hint'],

                'first_name'=>[],

            ),

            'buttons'=>array(

                'submit'=>array(

                    'type'=>'submit',

                    'label'=>'Next'

                ),

            ),

        ), $this);

    }

    

    //this is the CForm, it's working

    public function getForm2() {

        return new CForm(array(

            'showErrorSummary'=>true,

            'elements'=>array(

                'title'=>['hint'=>'my hint'],

                'last_name'=>['hint'=>'my hint'],

                'first_name'=>[],

            ),

            'buttons'=>array(

                'submit'=>array(

                    'type'=>'submit',

                    'label'=>'Next'

                ),

            )

        ), $this);

    }


}



the view:




<?php

echo $event->sender->menu->run();

echo '<div>Step '.$event->sender->currentStep.' of '.$event->sender->stepCount;

echo '<h3>'.$event->sender->getStepLabel($event->step).'</h3>';


echo CHtml::tag('div',array('class'=>'form'),$form);



Can anybody tell me, what’s wrong with my code?

If I use


$form->render()

in my view, the result is an exception:

Person and its behaviors do not have a method or closure named "beginWidget".

I’m absolutely confused.

I want to make a dependent drop-down list that depend on another drop-down list. As I have understood, I will need to implement the dependent drop-down list using ajax.

My question is: How to use ajax query in wizardBehavior form?

Note: Both drop-down list are populated from database.

Has anyone used the OnExpiredStep? I can’t get it to show a flash message.