0

I'm just learning zf2, and the basic tutorial from official document is great. Now, I would like to challenge myself to create multi page form in one page, something like that http://demo.stepblogging.com/multi-step-form/

So, currently I have two forms called "Contact Form" and "Album Form".

The idea is i want to split to 2 forms. The problem is when i finish all the fields on the first form, i'm not sure how to go to next form. I'm not sure i can do the logic at Controller, what i know most of the online tutorials are using javascript to handle the next and back button. Or maybe have better idea?

So this is my Controller page.

 public function multipleAction(){
    $formOne = new ContactForm();
    $formTwo = new AlbumForm();

    $formOne->get('next')->setValue('Next');
    $request = $this->getRequest();

    if($request->isPost()){ 
        $aa = new ContactFilter();
        $formOne->setInputFilter($aa); 
        $formOne->setData($request->getPost()); 

        if ($formOne->isValid()) {
           //save session 
           //maybe display second form or any other solution
        }
    }

my multiple.phtml page contains 2 forms

<ul id="signup-step">
<li id="contact" class="active">Contact</li>
<li id="album">Album</li>
</ul>

<?php
 $form_one = $this->form_one;

 //$form_one->setAttribute('action', $this->url('album', array('action' => 'multiple')));
 $form_one->prepare();

 //echo $_SESSION['name'];
 echo $this->form()->openTag($form_one); ?>

 <div id="contact-field">
<legend>Contact</legend>
<?php
 echo $this->formHidden($form_one->get('id'));

 echo $this->formLabel($form_one->get('name')).'<br>';
 echo $this->formInput($form_one->get('name'))."<br>";
 echo $this->formElementErrors($form_one->get('name'));

 echo $this->formLabel($form_one->get('artist')).'<br>';
 echo $this->formInput($form_one->get('artist'))."<br>";
 echo $this->formElementErrors($form_one->get('artist'));


 echo $this->formLabel($form_one->get('address')).'<br>';
 echo $this->formInput($form_one->get('address'))."<br><br>";
 echo $this->formElementErrors($form_one->get('address'));

 echo $this->formSubmit($form_one->get('next'));
 echo $this->form()->closeTag($form_one);
 ?>

 <?php
 $form_two = $this->form_two;
 $form_two->prepare();

 echo $this->form()->openTag($form_two); ?>

 <div id="album-field" >
<legend>Album</legend>
<?php 
 echo $this->formLabel($form_two->get('title')).'<br>';
 echo $this->formInput($form_two->get('title'))."<br>";
 echo $this->formElementErrors($form_two->get('title'));

 echo $this->formLabel($form_two->get('artist'))."<br>";
 echo $this->formInput($form_two->get('artist'))."<br>";
 echo $this->formElementErrors($form_two->get('artist'));
 echo $this->form()->closeTag($form_two);
 ?>

weikian
  • 260
  • 2
  • 5
  • 14

3 Answers3

0

i don't think i have understand exactly what you want, but if you mean multiple steps with different form, so you have just to put the previous step result in session,

Jkhaled
  • 435
  • 5
  • 7
  • Sorry for making u confuse. I mean multiple steps with different forms but in one page. Is that possible? What i found in other tutorials , they mostly using js or jquery. I not sure zf2 have any function to help for multi step form. I want to create something like that http://demo.stepblogging.com/multi-step-form/ – weikian Sep 25 '15 at 12:09
0

your question is fuzzy. your given link is also done by jquery!... As far as I understand you want this demo page behavior without using js/jquery.

1. break this one form into three form. For easiness add a hidden field step
2. make next and back button input type submit
3. after submit in your action check submitted value and determine what you want ...[show next form or whatever]
Atiqur
  • 3,802
  • 1
  • 25
  • 26
  • Thanks for response. I prefer to do it without js or jquery. Do u have sample how to do at Controller ? – weikian Sep 28 '15 at 12:57
0

The code below is very crude and is only for example purposes (made this in 10 mins and looks like it)

So basically all we are doing is the following -

  1. Creating a session
  2. Checking if there is any data in the session for that particular form, if there is one then use setData() to set the data on the form
  3. If the form posts data, then validate & filter it and then save that data to the session
  4. The "Submit" button value in the form is used to determine the navigation path i.e. previous or next page.
  5. The final page will save data from the session to the DB (or whatever you want to do with it) and of course destroy the session as well.

Controller

/** @var Zend\Session\Container Session Object */
private $session;

public function __construct()
{
    // Put a meaningful name in the constructor
    $this->session = new Container();
}

public function page1Action()
{
    // This should really be injected...
    $form = new Form\Form1();

    // Proper validation & filtering needs to be done for every form (this is example only)
    $form->setInputFilter(new InputFilter());

    // Populates form data from the session if it already exists
    if (isset($this->session->form1Inputs)) {
        $form->setData($this->session->form1Inputs);
    }

    $request = $this->getRequest();

    if ($request->isPost()) {
        $form->setData($request->getPost());

        if ($form->isValid()) {
            $formData = $form->getData();

            // Saves the new data to the session
            $this->session->form1Inputs = $formData;

            // Redirects to next page
            if ($formData['Next'] === 'Next') {
                $this->redirect()->toRoute('application', ['controller' => 'Index', 'action' => 'page2']);
            }
        }
    }

    return new ViewModel(['form' => $form]);
}

public function page2Action()
{
    // This should really be injected...
    $form = new Form\Form2();

    // Proper validation & filtering needs to be done for every form (this is example only)
    $form->setInputFilter(new InputFilter());

    // Populates form data from the session if it already exists
    if (isset($this->session->form2Inputs)) {
        $form->setData($this->session->form2Inputs);
    }

    $request = $this->getRequest();

    if ($request->isPost()) {
        $form->setData($request->getPost());

        if ($form->isValid()) {
            $formData = $form->getData();

            // Saves the new data to the session
            $this->session->form2Inputs = $formData;

            // Redirects to next or previous page
            if ($formData['Next'] === 'Next') {
                $this->redirect()->toRoute('application', ['controller' => 'Index', 'action' => 'page3']);
            } elseif ($formData['Previous'] === 'Previous') {
                $this->redirect()->toRoute('application', ['controller' => 'Index', 'action' => 'page1']);
            }
        }
    }

    return new ViewModel(['form' => $form]);
}

public function page3Action()
{
    // This should really be injected...
    $form = new Form\Form3();

    // Proper validation & filtering needs to be done for every form (this is example only)
    $form->setInputFilter(new InputFilter());

    // Populates form data from the session if it already exists
    if (isset($this->session->form2Inputs)) {
        $form->setData($this->session->form2Inputs);
    }

    $request = $this->getRequest();

    if ($request->isPost()) {
        $form->setData($request->getPost());

        if ($form->isValid()) {
            $formData = $form->getData();

            // Saves the new data to the session
            $this->session->form3Inputs = $formData;

            // Finalise or redirect to previous page
            if ($formData['Finalise'] === 'Finalise') {
                // Save all data to DB from session & destroy
            } elseif ($formData['Previous'] === 'Previous') {
                $this->redirect()->toRoute('application', ['controller' => 'Index', 'action' => 'page2']);
            }
        }
    }

    return new ViewModel(['form' => $form]);
}

Form 1

public function __construct($name = null)
{
    parent::__construct($name);

    $this->add(['name' => 'Form1Text1', 'type' => 'Text', 'options' => ['label' => 'Form 1 Text 1 : ']]);

    $this->add(['name' => 'Form1Text2', 'type' => 'Text', 'options' => ['label' => 'Form 1 Text 2 : ']]);

    $this->add(['name' => 'Next', 'type' => 'Submit', 'attributes' => ['value' => 'Next']]);
}

Form 2

public function __construct($name = null)
{
    parent::__construct($name);

    $this->add(['name' => 'Form2Text1', 'type' => 'Text', 'options' => ['label' => 'Form 2 Text 1 : ']]);

    $this->add(['name' => 'Form2Text2', 'type' => 'Text', 'options' => ['label' => 'Form 2 Text 2 : ']]);

    $this->add(['name' => 'Next', 'type' => 'Submit', 'attributes' => ['value' => 'Next']]);
    $this->add(['name' => 'Previous', 'type' => 'Submit', 'attributes' => ['value' => 'Previous']]);
}

Form 3

public function __construct($name = null)
{
    parent::__construct($name);

    $this->add(['name' => 'Form3Text1', 'type' => 'Text', 'options' => ['label' => 'Form 3 Text 1 : ']]);

    $this->add(['name' => 'Form3Text2', 'type' => 'Text', 'options' => ['label' => 'Form 3 Text 2 : ']]);

    $this->add(['name' => 'Previous', 'type' => 'Submit', 'attributes' => ['value' => 'Previous']]);
    $this->add(['name' => 'Finalise', 'type' => 'Submit', 'attributes' => ['value' => 'Finalise']]);
}
Rahul Datta Roy
  • 160
  • 1
  • 4