Stateful Forms and Wizards -- Howto?
Rate Topic:

I have an employee-tracking app that needs to be able to take basic information (name, address, etc.) from a prefilled Excel sheet. I'll need to turn the one sheet into information in a few tables once the user uploads it and answers some questions. In short, I'll need a wizard for importing csv data.

It looks like Stateful Forms were created for this purpose. I cannot find any information about how to implement a wizard with Stateful Forms. Can anyone orient me a bit? Thanks in advance.

Thanks, cms, that's a useful pointer for making a wizard in php. I'll also add that the hangman demo uses Stateful Forms, and is the best example in Yii of their use that I could find. If anyone else has more about Yii, stateful forms, and wizards, I would still love to get more pointers.

Thanks, cms, that's a useful pointer for making a wizard in php. I'll also add that the hangman demo uses Stateful Forms, and is the best example in Yii of their use that I could find. If anyone else has more about Yii, stateful forms, and wizards, I would still love to get more pointers.

best wishes,

Greg

Hi I have similar challenges right now. Which solution did you manage to go with within yii framework?

There are a couple of pieces that need to be put into place for it to all work. I will outline my understanding and you can ask me questions if it's not detailed enough. The basic idea to start with is that a wizard needs multiple pages sharing information to work. So this information needs to be passed from the page to the controller to the next page to the controller to the next page, etc.

Starting with the controller, whatever you want passed along, you need to store in the controller using setPageState(). This creates an entry in a private associative array in the controller with the key and value that you pass.

The values set in the controller with setPageState() are automatically stored in a view containing a StatefulForm. Each page of your wizard (except maybe the first and the last) needs to have a StatefulForm on it. This will create a hidden value called YII_PAGE_STATE that has an encoded copy of all the values set in the controller. The controller that gets the POST of a page with a StatefulForm will then be able to retrieve the values with getPageState(). Each page will also have fields of data that get filled in and POSTed as usual (in addition to the YII_PAGE_STATE) andthe controller processes these and adds what it needs to the page stateto be passed down the line.

To summarize, values get POSTED from a page, set in the controller with setPageState(), get passed to the next page with a StatefulForm, and retrieved in the controller with getPageState(). It goes: page to controller to page to controller to page to controller, etc. and you can have as many pages as you want sharing data.

The only effect making a wizard had on the model was that I didn't use many models. My first page took scalar information about the file to upload, the number of lines to read, etc. I had a FormModel for data validation. My other pages showed the table to import and allowed the user to edit the fields. There was not much use for FormModel's for these pages, so the controller did the validation work here.

It was kind of a fat-controller approach. Besides not using models much, I had a single ImportController that took control each time a page of the wizard was passed back. It handled everything, with a bit of help from the one FormModel mentioned above and a view for each page of the wizard.

There are a couple of pieces that need to be put into place for it to all work. I will outline my understanding and you can ask me questions if it's not detailed enough. The basic idea to start with is that a wizard needs multiple pages sharing information to work. So this information needs to be passed from the page to the controller to the next page to the controller to the next page, etc.

Starting with the controller, whatever you want passed along, you need to store in the controller using setPageState(). This creates an entry in a private associative array in the controller with the key and value that you pass.

The values set in the controller with setPageState() are automatically stored in a view containing a StatefulForm. Each page of your wizard (except maybe the first and the last) needs to have a StatefulForm on it. This will create a hidden value called YII_PAGE_STATE that has an encoded copy of all the values set in the controller. The controller that gets the POST of a page with a StatefulForm will then be able to retrieve the values with getPageState(). Each page will also have fields of data that get filled in and POSTed as usual (in addition to the YII_PAGE_STATE) andthe controller processes these and adds what it needs to the page stateto be passed down the line.

To summarize, values get POSTED from a page, set in the controller with setPageState(), get passed to the next page with a StatefulForm, and retrieved in the controller with getPageState(). It goes: page to controller to page to controller to page to controller, etc. and you can have as many pages as you want sharing data.

The only effect making a wizard had on the model was that I didn't use many models. My first page took scalar information about the file to upload, the number of lines to read, etc. I had a FormModel for data validation. My other pages showed the table to import and allowed the user to edit the fields. There was not much use for FormModel's for these pages, so the controller did the validation work here.

It was kind of a fat-controller approach. Besides not using models much, I had a single ImportController that took control each time a page of the wizard was passed back. It handled everything, with a bit of help from the one FormModel mentioned above and a view for each page of the wizard.

That's all I can think of for now. Hope this helps.

Greg

Hi Greg,

Thank you indeed for this info. I will try it out and get back to you in 48 hours...