6

この記事を読みました: http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/

それは非常に興味深く、うまく機能します。

同じことをする必要がありますが、サブフォームを使用します。つまり、ユーザーがボタンを押すと、ajax を介して、既存のフォームにサブフォームを追加、アタッチ、および表示するアクションを呼び出します。

例:
ユーザーが子供の名前と姓を入力する必要があるフォームがあるため、[子供を追加] ボタンがあります。ユーザーがそのボタンを押すと、サブフォームが既存のフォームに追加されて表示されます。送信すると、その記事の例とまったく同じように検証されます。唯一の違いは、そこに 1 つのフィールドを追加するだけであるということです。サブフォームを追加する必要がありますが、まったく同じ方法です。

アクションで次のことを試しました( 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 呼び出しが成功すると、それを表示するだけです。

問題は、送信時にフォームを検証しますが、追加したばかりの新しいサブフォームが失われていることです。これは、要素が 1 つだけの記事では発生しません。サブフォームを既存のフォームに追加するだけでよいと思いますが、どうすればよいでしょうか?

4

1 に答える 1

2

サブフォーム要素にサブフォームのプレフィックスを追加します。サブフォームを表すために接頭辞「子」を使用しました。各サブフォームは、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 関数を簡素化します。この機能を利用するようにコードを編集しました。

ペーストビンで完全なコードを参照してください

これは、サブフォーム要素に配列表記を提供する、begsTo を使用した別のソリューションです: http://www.stephenrhoades.com/?p=364

于 2012-11-03T17:00:37.560 に答える