Welcome, Guest. Register Now!
   
Mark Forums Read Mark Forums Read Mark Forums Read


Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 04-07-2008, 09:01 AM
MiK MiK is offline
Junior Member
 
Join Date: Mar 2008
Location: Ancona, Italy
Posts: 17
Send a message via MSN to MiK
Exclamation Multi Page Forms Help

Hello,
i'm looking for a quick&clean way (i'm asking too much.. i know ) to handle multipage forms.
Since the Zend_Form component is still not fully complete (File Upload and Multi Page support are missing) i can't figure out finding a way to handle them without repeating much code.

I tried to implement that code listed on the tutorial, but i found it incorrect, as there's some code which should go in the controller and not in the class extending zend_form or viceversa, and leads to a very tedious process in my case where i need different forms of this kind.

At this point i will make a step back and move out of zend_form component until is 100% complete.

Could you please post some examples (or links) on form handling without zend_form?

Any help is appreciated.
Thanks.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-09-2008, 09:43 AM
MiK MiK is offline
Junior Member
 
Join Date: Mar 2008
Location: Ancona, Italy
Posts: 17
Send a message via MSN to MiK
Default Solution found (almost working)

Hello,
Since i haven't found any solution to my issue, i managed to write something by myself.

I wrote an external extensible class, which provides (or tries to do so) the following features:

- Simple multi page form handling (all forms are extensions of my class)
- Data persistence using sessions
- Arbitrary step retrieving (in case you would edit some previous submitted step)
- Data validation/filtering for each step
- Stored data retrieving/deleting for each step

But does NOT (yet?) provide the following:

- Multi instance form handling (when the user opens multiple instances of the same form, using tabs for example, this uses the same session.. can't find a workaround for this)
- Conditional step retrieving (i don't need this, at the moment, neither i've got any idea on how implement this)
- Something else

Dependencies:
- Zend Framework version 1.5.1
- Zend_Form_*
- Zend_Session_*
- Zend_Controller_Request_Http

Here's a code snippet from my controller, just to let you see how it works:
PHP Code:
class TestController extends Controller
{
    function 
testAction()
    {
        require_once(
'Classes/Forms/MyForm.php');
        
$form = new Form_MyForm();

        
$form->setStepAction('/test/test')
             ->
setStepMethod('post')
             ->
setStepAttrib('enctype''multipart/form-data')
             ->
setStepAttrib('id''myform')
             ->
setStepPrefix('step_')
             ->
setSessionNamespace('mysession')
             ->
build();

        
$request $this->getRequest();

        
// If this is a POST request ...
        
if ($request->isPost()) {
            
// i get the submitted form id
            
$step $form->getCurrentStepId($request);

            
$data $request->getPost();

            
// if submitted step data is valid ..
            
if ($form->isValidStep($step$data)) {
                
// store data into the session
                
$form->saveStep($step);
                
// get the next step available
                
$currentStep $form->getNextStep($step);
                
// if there's no next step ...
                
if ($currentStep === false) {
                    
// ... we reached the end and we should handle form data
                    
Zend_Debug::dump$form->getValues(), "FORM COMPLETED");
                    exit;
                }
            
// if data is not valid, we get the same form again
            
} else {
                
$currentStep $form->getStep($step);

            }
        
// If this is a normal GET request (/test/test/step/:id)
        
} else {
            
// We get the step id requested by the user
            
$step = (int) $request->getParam('step');
            
            
// If no step is requested, we assume the first step
            // and reset session data. 
            
if ($step == 0) {
                
$step 1;
                
$form->clearSession();
            }
            
            
// Gets the requested step (if exists)
            
if ($currentStep $form->getStep($step)) {
                
// If there's pre-submitted data in session, we use id
                // to repopulate form
                
$form->populateStep($step);
                
// Deletes data from session
                // (user should re-submit form again)
                
$form->deleteStep($step);
            
// This is just an error sample, we may throw an exception...
            
} else {
                
$currentStep "STEP REQUESTED IS NOT VALID";
            }
        }
       
        
// I use Smarty as View Renderer
        
$this->view->form $currentStep;
        echo 
$this->view->render('testform.tpl');
    }

If someone is interested, i will post the rest of the code (class, and form example).

Just a little disclaimer:
Quote:
I am not a zend framework expert, nor a professional php developer.
This is just an attempt to make the process of creating multi page forms, a bit less
tedious and a bit more maintenable. The code may be not written at best,
and requires improvements for sure.

Last edited by MiK : 04-10-2008 at 01:37 PM.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-11-2008, 11:15 AM
Junior Member
 
Join Date: Apr 2008
Location: Madrid, Spain
Posts: 1
Default

Hello,
I'm also trying to use multi page forms with Zend_Form following the tutorial but as you said it's wrong at some points.

I think your code looks nice so, if it really works I'm interested on it.

So, could you reply with the whole code? You know: controller, form class and view (.phtml files). It'd help me a lot


Thanks and good job!!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-11-2008, 03:33 PM
MiK MiK is offline
Junior Member
 
Join Date: Mar 2008
Location: Ancona, Italy
Posts: 17
Send a message via MSN to MiK
Default

Thanks for your interest.

Since i'm currently still developing the class, i don't have a "STABLE" release.
Please allow a couple of days in order to let me build a working example, and
so i will post the complete code as attachment here.

One of my last edit was the ability to fetch an array of a subform elements ( Multipage_Form::getStepElements() ) in order to pass it directly to the view,
and without being limited by zend_form decorators behaviour.

Something like:
PHP Code:
class MyController {
  
// .. Some other code ..
  
$this->view->form $form->getStepElements($stepId);
  echo 
$this->view->render('mytemplate');

And in the view (as told before, i use smarty_view as view renderer):
HTML Code:
<table>
  <tr>
   <td>{$form.field1->getLabel()}</td>
   <td>{$form.field1}</td>
  <tr>
   <td colspan="2">{$form.submit}</td>
  </tr>
</table>
I've got too much work these days, i hope i'll be able to post the code within Monday. I'll keep you updated.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-12-2008, 08:19 PM
MiK MiK is offline
Junior Member
 
Join Date: Mar 2008
Location: Ancona, Italy
Posts: 17
Send a message via MSN to MiK
Default Class with examples

Finally i got it...

I created a little zend framework enviroment with a couple of very simple
examples.

Just copy the ZF libraries to /library/Zend and you're ready.

The class is located in /library/Form
All the forms are in /application/forms

Download: MultiPage_Form_with_Examples.zip
Class Documentation: MultiPage_Form_PhpDoc.zip

Last edited by MiK : 04-12-2008 at 08:50 PM.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 07-16-2008, 09:28 AM
Junior Member
 
Join Date: Jul 2008
Posts: 1
Default Thank you!

Thank you for your code MiK, it's really helpful! I like the idea of having only one controller action for all the steps, so it behaves as one page form.
It works in Virtual Host alright, but to make it work in a subdirectory of document root, you have to change the paths in views to make it work properly. This is a common problem. I managed that with the baseUrl() view helper, after setting FrontController->setBaseUrl().
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 07-16-2008, 01:10 PM
MiK MiK is offline
Junior Member
 
Join Date: Mar 2008
Location: Ancona, Italy
Posts: 17
Send a message via MSN to MiK
Default You're welcome!

Nice to hear that someone thinks that my code is useful
Thanks for your support..

FYI, I found that solution a bit limited because i haven't found a way to retrieve a particular subform depending on user selection. Take the example of a "Choose a type of payment" form where you have a dropdown box with values: "Cheque", "Credit Card", "Money Order" where each selection must end on a different form requesting payment details... (Conditional step retrieving).

Another problem is that, since we use a static session namespace to persist data between steps, when the user opens multiple instances of the same form in his browser, this would overwrite session data..

Now, this class works well when you're using it on simple forms where you don't need these features, but when you have to handle complex forms it becomes useless...

The only way i found to fix these issues is to span the form across multiple controller actions (without using this class), using a dynamically-created session id (eg. current timestamp) to create the namespace where to store form data preserving form uniqueness. Doing so, you will be able to fetch from every step action the previous inserted data and make your checks to have the correct form loaded (and implement conditional subforms).

This is just a little note

Hope this helps.
Regards,
Michele
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 07-17-2008, 01:43 PM
Junior Member
 
Join Date: Jul 2008
Location: Ahmedabad
Posts: 7
Default

Quote:
Originally Posted by median View Post
Thank you for your code MiK, it's really helpful! I like the idea of having only one controller action for all the steps, so it behaves as one page form.
It works in Virtual Host alright, but to make it work in a subdirectory of document root, you have to change the paths in views to make it work properly. This is a common problem. I managed that with the baseUrl() view helper, after setting FrontController->setBaseUrl().
I have set baseurl according to subdirectory but i have problem with common directory path like images, css which i have set in config.ini

How could I get those path in view controller (tpl or phtml files)?
__________________
Amit Shah
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 06:14 PM.