2017-09-14 62 views
0

我有Symfony表單收集域的問題。我有一個父窗體,其中有兩個字段是表單集合。除非我用無效數據提交表單,否則一切工作都很好。表單集合字段的錯誤將輸出到頁面上的表單下方。我一直在閱讀關於這些字段上的error_bubbling的文檔,並意識到對於CollectionType字段,它默認爲true。因此,我已在每個字段上將其設置爲false,並且錯誤仍未映射到表單上的字段。與域無關的Symfony動態表單收集錯誤

收集字段可以通過前端的javascript動態添加到頁面。我注意到的是,在我的標記中,在我提交表單之前,有兩個錯誤的<div class=""form-group">被添加到我的標記中,而我在模板中沒有輸出這個標記。當表單被提交併且無效時,則錯誤在這些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){} 

The Template;

{% 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> 

我確實希望這能幫助那些發現自己陷入同樣困境的人!