Search code examples
phpzend-frameworkzend-form

Processing Zend_Form dynamically generated elements


I need to create a form where the elements (texbox, select, ..) will be dynamically inserted. Right now I have created a empty Form file with just a hidden element and them in my controller I go inserting elements according to certain conditions.

My form file:

class Form_Questions extends Zend_Form {
    public function __construct()  {
        parent::__construct($options);
        $this->setName('Questions');

        // Hidden Label for error output        
        $hiddenlabel = new Zend_Form_Element_Hidden('hiddenlabel');
        $hiddenlabel->addDecorator(new Form_Decorator_HiddenLabel());

        $this->addElements( array($hiddenlabel) );
   }
}

In the controller I have something like:

...

$form = new Form_Questions();       
$request = $this->getRequest();

if ($request->isPost())
{
  $formData = $request->getPost();

  if ($form->isValid($request->getPost()))
  {
    die(var_dump($form->getValues()));
  }
}
else
{
  //... add textbox, checkbox, ...

  // add final submit button
  $btn_submit = new Zend_Form_Element_Submit('submit');
  $btn_submit->setAttrib('id', 'submitbutton');
  $form->addElement($btn_submit);

  $this->view->form = $form;
}

The form displays fine but the validation is giving me big trouble. My var_dump() only shows the hidden element that is staticly defined in the Form file. It does not save the dinamic elements so altought I can get them reading what's coming via POST, I can not do something like

$form->getValue('question1');

It behaves like if Zend uses the Form file to store the values when the submit happend, but since the elements are created dinamically they do not persist (either their values) after the post so I can not process them using the standar getValue() way.

I would appreciate any ideas on how to make them "live" til after the post so I can read them as in a normal form.


Solution

  • It sounds like the form is dynamic in the sense that the questions come from a db, not in then sense that the user modifies the form itself to add new questions.

    Assuming this is the case, then I wouldn't add the question fields in the controller. Rather, I'd pass the questions to the form in the constructor and then add the question fields and the validators in the form's init() method. Then in the controller, just standard isPost() and isValid() processing after that.

    Or, if you are saying that the questions to be added to the form are somehow a consequence of the hidden label posted, then perhaps you need two forms and two actions: one for the hidden field form and another for the questions.