处理Zend_Form动态生成的元素

时间:2011-06-22 14:51:07

标签: php zend-framework zend-form

我需要创建一个表单,其中将动态插入元素(texbox,select,..)。现在我创建了一个空的Form文件,只有一个隐藏元素,在我的控制器中我会根据特定条件插入元素。

我的表单文件:

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) );
   }
}

在控制器中我有类似的东西:

...

$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;
}

表单显示正常,但验证给我带来了很大的麻烦。我的var_dump()只显示在Form文件中静态定义的隐藏元素。它没有保存dinamic元素所以altought我可以让他们通过POST阅读什么,我不能做像

$form->getValue('question1');

它的行为就像Zend使用Form文件在提交发生时存储值,但由于元素是以dinamically方式创建的,因此它们不会在post之后保留(或者它们的值)所以我无法使用标准getValue处理它们()方式。

我很感激有关如何让它们“直播”到帖子之后的任何想法,所以我可以像普通形式一样阅读它们。

3 个答案:

答案 0 :(得分:1)

您正在调用isValid()getValues()方法的表单实际上是您的“空”表单 - 您已经将它实例化了几行并且没有在其中添加任何元素点。

请记住POST只发送一个fieldName =>数组。 fieldValue类型,它实际上不发送Zend_Form对象。

如果不知道自己要实现的目标,很难提出新的解决方案。通常最好立即将所有可能的元素添加到Zend_Form中,然后仅使用视图脚本中需要的元素,即echo $this->form->myField;。这将允许isValid()处理表单的所有元素。

答案 1 :(得分:0)

听起来这个表单是动态的,因为问题来自数据库,而不是那时用户修改表单本身来添加新问题。

假设是这种情况,那么我不会在控制器中添加问题字段。相反,我将问题传递给构造函数中的表单,然后在表单的init()方法中添加问题字段和验证器。然后在控制器中,之后只需标准isPost()isValid()处理。

或者,如果您说要添加到表单中的问题是某种方式是发布隐藏标签的结果,那么您可能需要两种形式和两种操作:一种用于隐藏字段形式,另一种用于问题。

答案 2 :(得分:0)

好的,我提出的最简单的解决方案 - 就我的情况而言,考虑到我正在使用的代码的真正原因是使用我的模型中的方法从数据库中加载我需要的所有问题(类似于fetchQuestions( )),它们在我的控制器中我遍历记录集并根据记录集的当前问题创建表单元素。 元素堆叠在一个传递给我的Form构造函数的数组中。在表单构造函数中,我读取数组并生成所有动态元素。我他们只是将形式回应到视图中。

我似乎不知道为什么覆盖Form构造函数是个坏主意,因为我也无法使用任何set / get方法将它传递给我的表单。