提交时使用 ajax 将子表单添加到表单

发布于 2024-12-14 16:08:02 字数 1388 浏览 3 评论 0原文

我读了这篇文章: http://www.jeremykendall.net/ 2009/01/19/dynamically-adding-elements-to-zend-form/

这非常有趣,而且工作得很好。

我需要做同样的事情,但是使用子表单。我的意思是,当用户按下按钮时,我通过 ajax 调用一个操作,将子表单添加、附加并显示到我现有的表单中。

例如:
我有一个表单,用户必须填写其孩子的姓名,因此有一个“添加孩子”按钮。当用户按下该按钮时,应将子表单添加到我现有的表单中并显示。提交后,它将像该文章中的示例一样进行验证。唯一的区别是他只在其中添加了一个字段。我需要添加一个子表单,但方式完全相同。

我在我的操作中尝试了以下操作(由 Ajax 调用):

public function clonerecursivegroupAction()
{
    $this->_helper->layout->disableLayout();
    $ajaxContext = $this->_helper->getHelper('AjaxContext');
    $ajaxContext->addActionContext('clonerecursivegroup', 'html')->initContext();

    $id = $this->_getParam('id', null);

    $subform1 = new Zend_Form_SubForm();

    $Element1 = $subform1->createElement('text', 'text1');
    $Element1->setLabel('text1')->setRequired(true);
    $Element2 = $subform1->createElement('text', 'text2');
    $Element2->setLabel('text2')->setRequired(false);

    $subform1->addElement($Element1);
    $subform1->addElement($Element2);

    $this->view->field = $subform1->__toString();
}

这几乎有效。
此操作的视图返回子表单的 html 代码,因此在我的 ajax 调用成功后,我只显示它。

问题是,提交时它会验证表单,但它丢失了刚刚添加的新子表单。在只有一个元素的文章中不会发生这种情况。我想我只需要将子表单添加到现有表单中,但是如何呢?

I read this article:
http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/

That was very interesting and it works fine.

I need to do the same but with a SubForm. I mean that when a user presses a button, I call, via ajax, an action that adds, attaches and displays a subform to my existing form.

For example:
I have a form where a user must fill in the name and surname of his children, so there is a button "Add Child". When the user presses that button a SubForm should be added to my existing form and displayed. On submit it will validate exactly like the example in that article. The only difference is that in there he just adds a single field. I need to add a SubForm, but in exactly the same way.

I tried the following in my action ( called by Ajax ):

public function clonerecursivegroupAction()
{
    $this->_helper->layout->disableLayout();
    $ajaxContext = $this->_helper->getHelper('AjaxContext');
    $ajaxContext->addActionContext('clonerecursivegroup', 'html')->initContext();

    $id = $this->_getParam('id', null);

    $subform1 = new Zend_Form_SubForm();

    $Element1 = $subform1->createElement('text', 'text1');
    $Element1->setLabel('text1')->setRequired(true);
    $Element2 = $subform1->createElement('text', 'text2');
    $Element2->setLabel('text2')->setRequired(false);

    $subform1->addElement($Element1);
    $subform1->addElement($Element2);

    $this->view->field = $subform1->__toString();
}

This almost works.
The view of this action returns the html code of the SubForm, so on success of my ajax call I just display it.

The problem is that on submit it validates the form but it has lost the new subform just added. That does not happen in the article with just one element. I think I just need to add the SubForm to the existing Form, but how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百变从容 2024-12-21 16:08:05

将子表单的前缀添加到子表单元素。我使用前缀“child”来表示子表单。每个子表单将被创建为 child1、child2 等等。

public function clonerecursivegroupAction()
{
       //.. Other code

        $subform = new Zend_Form_SubForm();
    $subform->setIsArray(true);
    $subform->setName("child$id");
    $Element1 = $subform->createElement('text', "newfield$id");
    $Element1->setLabel("newfield$id")
             ->setRequired(true);
    $subform->addElement($Element1);

    $Element1 = $subform->createElement('text', "nextfield$id");
    $Element1->setLabel("nextfield$id")
             ->setRequired(true);

    $subform->addElement($Element1);

    $this->view->field = $subform; 
 // Rest of your statements

}

然后,在 preValidation 函数中,使用子表单前缀而不是字段名称来过滤子表单:

   public function preValidation(array $data) {
         // array_filter callback
        function findForms($field) {
         // return field names that include 'child'
          if (strpos($field, 'child') !== false) {
               return $field;
           }
         }

      $subForms = array_filter(array_keys($data), 'findForms'); //filter the subform elements

      $children = array();
      foreach ($subForms as $subform) {

          if (is_array($data[$subform])) { 
        $children[$subform] = $data[$subform];
      }

       }

       //Iterate the children
       foreach ($children as $key => $fields) { //$key = subformname, $field=array containing fiend names and values

       // strip the id number off of the field name and use it to set new order
       $order = ltrim($key, 'child') + 2;
       $this->addNewForm($key, $fields, $order);
     }

}

Add New Form 函数创建每个子表单并附加到主表单:

     public function addNewForm($form, $elements, $order) {

            $subform = new Zend_Form_SubForm();
    $subform->setIsArray(true);
    foreach ($elements as $key => $el) {
          $Element1 = $subform->createElement('text', $key);
              $Element1->setLabel($form.$key)
             ->setValue($el)
                 ->setRequired(true);
                   $subform->addElement($Element1);
    }
        $this->addSubForm($subform, $form, $order);

    }

[编辑] 对子表单使用 setIsArray 创建每个元素子表单的数组元素。它简化了 preValidate 函数。编辑代码以利用此功能。

请参阅pastebin中的完整代码

这是另一个使用belongsTo的解决方案,为子表单元素提供数组表示法:http://www.stephenrhoades.com/?p=364

Add a prefix of the subform to the subform elements. I used the prefix "child" to represent the subforms. Each subform will be created as child1, child2 and so on.

public function clonerecursivegroupAction()
{
       //.. Other code

        $subform = new Zend_Form_SubForm();
    $subform->setIsArray(true);
    $subform->setName("child$id");
    $Element1 = $subform->createElement('text', "newfield$id");
    $Element1->setLabel("newfield$id")
             ->setRequired(true);
    $subform->addElement($Element1);

    $Element1 = $subform->createElement('text', "nextfield$id");
    $Element1->setLabel("nextfield$id")
             ->setRequired(true);

    $subform->addElement($Element1);

    $this->view->field = $subform; 
 // Rest of your statements

}

Then, in the preValidation function, filter the subforms using the subform prefix, instead of the field name:

   public function preValidation(array $data) {
         // array_filter callback
        function findForms($field) {
         // return field names that include 'child'
          if (strpos($field, 'child') !== false) {
               return $field;
           }
         }

      $subForms = array_filter(array_keys($data), 'findForms'); //filter the subform elements

      $children = array();
      foreach ($subForms as $subform) {

          if (is_array($data[$subform])) { 
        $children[$subform] = $data[$subform];
      }

       }

       //Iterate the children
       foreach ($children as $key => $fields) { //$key = subformname, $field=array containing fiend names and values

       // strip the id number off of the field name and use it to set new order
       $order = ltrim($key, 'child') + 2;
       $this->addNewForm($key, $fields, $order);
     }

}

Add New Form function creates each of the sub forms and attaches to the main form:

     public function addNewForm($form, $elements, $order) {

            $subform = new Zend_Form_SubForm();
    $subform->setIsArray(true);
    foreach ($elements as $key => $el) {
          $Element1 = $subform->createElement('text', $key);
              $Element1->setLabel($form.$key)
             ->setValue($el)
                 ->setRequired(true);
                   $subform->addElement($Element1);
    }
        $this->addSubForm($subform, $form, $order);

    }

[EDIT] Using setIsArray for a subform creates each element of the subform as an array element. It simplifies the preValidate function. Edited the code to utilize this feature.

See the complete code in pastebin

Here is another solution using belongsTo, providing array notation to the sub form elements : http://www.stephenrhoades.com/?p=364

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文