Ошибки коллекции динамических форм Symfony, не связанные с полями

У меня проблема с полем коллекции форм Symfony. У меня есть родительская форма, в которой есть два поля, которые представляют собой коллекции форм. Все работает абсолютно нормально, за исключением случаев, когда я отправляю форму с неверными данными. Ошибки для полей коллекции форм выводятся под формой на странице. Я прочитал документацию по error_bubbling для этих полей и понял, что для полей CollectionType по умолчанию установлено значение true. Поэтому я установил значение false для каждого поля, и все же ошибки не сопоставляются с полями в форме.

Поля коллекции могут динамически добавляться на страницу с помощью javascript во внешнем интерфейсе. Что я заметил, так это то, что в моей разметке, еще до того, как я отправил форму, к базе моей разметки добавлены два ошибочных <div class=""form-group">, которые я не вывожу в своем шаблоне. Когда форма отправлена ​​и недействительна, в этих div выводятся ошибки.

Код;

ТипФормы Элемента;

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

Будем очень благодарны любой помощи! Пробовал все, чтобы ошибки были в правильном месте.


person jackieb123    schedule 14.09.2017    source источник


Ответы (1)


Итак, для всех остальных я нашел ответ на эту загадку.

По сути, в то время как мой JS отображал форму на странице с помощью атрибута «прототип» в моем <tbody>, насколько было известно 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>

Я надеюсь, что это поможет кому-то еще, кто оказался в таком же затруднительном положении!

person jackieb123    schedule 15.09.2017