2017-09-14 25 views
0

Symfonyフォームコレクションフィールドに問題があります。フォームコレクションである2つのフィールドを持つ親フォームがあります。無効なデータでフォームを送信した場合を除いて、すべてが正常に機能しています。フォームコレクションフィールドのエラーは、ページのフォームの下に出力されます。これらのフィールドでerror_bubblingのドキュメントを読んで、CollectionTypeフィールドのデフォルト値がtrueであることを認識しています。したがって、私は各フィールドでfalseに設定し、エラーはフォームのフィールドにマッピングされません。Symfony動的フォームコレクションエラーがフィールドに関連付けられていません

コレクションフィールドは、フロントエンドのjavascriptを使用してページに動的に追加できます。私が気づいたのは、私のマークアップでは、フォームを提出する前に、私のテンプレートに出力していないマークアップのベースに2つの間違った2つのエラーがあります。フォームが送信され、有効でない場合、これらのdiv内でエラーが出力されています。

コードです。

ItemFormType;

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
     $builder 
      ->add('shop', ShopType::class, [ 
       'data_class' => Shop::class, 
       'label' => false, 
      ]) 
      ->add('purchase', PurchaseType::class, [ 
       'data_class' => Purchase::class, 
       'label' => false, 
      ]) 
      ->add('missing_items', CollectionType::class, [ 
       'entry_type' => MissingItemFormType::class, 
       'allow_add' => true, 
       'allow_delete' => true, 
       'label' => false, 
       'prototype' => true, 
       'error_bubbling' => false, 
      ]) 
      ->add('replaced_items', CollectionType::class, [ 
       'entry_type' => ReplacedItemFormType::class, 
       'allow_add' => true, 
       'allow_delete' => true, 
       'label' => false, 
       'prototype' => true, 
       'error_bubbling' => false, 
      ]) 
      ->add('submit', SubmitType::class) 
      ->getForm(); 
    } 

    /** 
    * Get the form name. 
    * 
    * @return string 
    */ 
    public function getName(): string 
    { 
     return 'missing_form'; 
    } 

    /** 
    * Set form options. 
    * 
    * @param OptionsResolver $resolver 
    * 
    * @return void 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => null, 
      'error_bubbling' => false 
     ]); 
    } 

コントローラ;

/** 
    * @Route("/", name="homepage") 
    * 
    * @param ClaimMailer $mailer 
    * @param Request $request 
    * 
    * @return Response 
    */ 
    public function indexAction(ClaimMailer $mailer, Request $request): Response 
    { 
     $purchase = [ 
      'shop' => new Shop(), 
      'purchase' => new Purchase(), 
     ]; 

     $form = $this->createForm(MissingFormType::class, $purchase); 

     $form->handleRequest($request); 

     if ($form->isSubmitted() && $form->isValid()) { 
      $this->store($form, $purchase); 

      // Send confirmation email. 
      $mailer->send(
       $purchase['purchase']->getEmail(), 
       $purchase['shop']->getName(), 
       $purchase['purchase']->getClaimReferenceNumber() 
      ); 

      return $this->render('form/form_complete.html.twig', [ 
       'purchase_id' => $purchase['purchase']->getPurchaseReferenceNumber(), 
      ]); 
     } 

     return $this->render('form/purchase_form.html.twig', [ 
      'form' => $form->createView(), 
     ]); 
    } 

    /** 
    * Store form data. 
    * 
    * @param Form $form 
    * @param array$claim 
    * 
    * @return void 
    */ 
    public function store(Form $form, $purchase){} 

テンプレートです。

{% block _missing_form_missing_items_entry_row %} 
    {% for field in form %} 
     <td> 
      {{ form_row(field) }} 
     </td> 
    {% endfor %} 
{% endblock %} 

{% block _missing_form_replaced_items_entry_row %} 
    {% for field in form %} 
     <td> 
      {{ form_row(field) }} 
     </td> 
    {% endfor %} 
{% endblock %} 

{% block website_body %} 
    <div class="row"> 
     <div class="col-lg-12"> 
      <div class="panel panel-default"> 
       <div class="panel-body"> 
        {{ form_start(form) }} 
        <div class="row"> 
         <div class="col-lg-6"> 
          {{ form_row(form.shop.name) }} 
          {{ form_row(form.shop.accountNumber) }} 
          {{ form_row(form.shop.email) }} 
          {{ form_row(form.shop.addressLine1) }} 
         </div> 
         <div class="col-lg-6"> 
          {{ form_row(form.shop.addressLine2) }} 
          {{ form_row(form.shop.town) }} 
          {{ form_row(form.shop.county) }} 
          {{ form_row(form.shop.postcode) }} 
         </div> 
        </div> 
        <div class="row"> 
         <h3>Missing Items</h3> 
         <table class="table missing_items"> 
          <tbody class="missing_items" data-prototype="{{ form_row(form.missing_items.vars.prototype)|e('html_attr') }}"></tbody> 
         </table> 
        </div> 
        <div class="row"> 
         <div class="col-lg-6"> 
          {{ form_row(form.purchase.receivedReplacement) }} 
         </div> 
         <table class="table replacement-items"> 
          <tbody class="replacement_items" data-prototype="{{ form_row(form.replaced_items.vars.prototype)|e('html_attr') }}"></tbody> 
         </table> 
        </div> 
        <div class="row"> 
         <div class="col-lg-6"> 
          {{ form_row(form.submit) }} 
         </div> 
        </div> 
        {{ form_end(form) }} 
        {% embed 'form/components/terms_and_conditions.html.twig' %}{% endembed %} 
       </div> 
      </div> 
     </div> 
    </div> 
{% endblock %} 

ご協力いただければ幸いです!正しい場所でエラーを取得するためにすべてを試しました。

答えて

0

他の誰かのために、私はこの難解な答えを見つけました。

基本的に、私のJSは、私の<tbody>にある "prototype"属性を使ってフォームをページにレンダリングしていましたが、Symfonyが認識していた限り、テンプレートにフィールドを明示的に出力していませんでした。その結果、テンプレートの最後に 'form_end(form)'を呼び出すと、アイテムフィールドのすべてのエラーが発生していました。

form_end(form)は、舞台裏でform_rest()を呼び出します。これは、基本的には明示的にレンダリングされていないフォームのフィールドを出力します。その結果、フォームの最後に検証エラーとそれぞれのフィールドが出力されます。ページ!

テンプレート内でこれらのフィールドを明示的に出力すると、エラーおよび関連するフィールドがそのままフォームに正しく表示されます。

<tbody class="missing_items" data-prototype="{{ form_row(form.missing_items.vars.prototype)|e('html_attr') }}"> 
    {% for field in form.missing_items %} 
     <tr class="item"> 
      <td>{{ form_row(field.quantity) }}</td> 
      <td>{{ form_row(field.description) }}</td> 
      <td>{{ form_row(field.invoiceNumber) }}</td> 
      <td>{{ form_row(field.invoiceDate) }}</td> 
      <td>{{ form_row(field.deliveryDate) }}</td> 
     </tr> 
    {% endfor %} 
</tbody> 

これは、同じ苦境で自分自身を見つけ出す他の人に役立つことを望みます。

関連する問題