Home > Net >  How to handle multiple form for the same entity type in the same view
How to handle multiple form for the same entity type in the same view

Time:11-30

I want to generate a list of form for all entries in a table (just two fields) with just a save and a delete button.

Here is the screen : https://i.imgur.com/4hW48Bw.png

Here is the form part :

templates\item\brand\_brandForm.html.twig

{{ form_start(formView) }}
<div >
    <div >
        #
        <br>
        {{brandId}}
    </div>
    <div >
        {{ form_row(formView.fullname) }}
    </div>
    <div >
        {{ form_row(formView.icon) }}
    </div>
    <div >
        <button  type="submit" name="update_button" value="{{brandId}}">
            <i ></i>
        </button>
        <button  type="submit" name="delete_button" value="{{brandId}}">
            <i ></i>
        </button>
    </div>
</div>
{{ form_end(formView) }}

Here is the view :

templates\item\brand\listForm.html.twig

{% extends 'base.html.twig' %}

{% block title %}Create a brand
{% endblock %}

{% block body %}
    <h1>Brand list form</h1>
    {% for form in forms %}
        {{form | raw}}
    {% endfor %}
{% endblock %}

Here is the FormType :

class BrandType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('fullname')
            ->add('icon');
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Brand::class,
        ]);
    }
}

And finally here is the controller part :

 public function editableList(EntityManagerInterface $em, Request $request, BrandRepository $brandRepository)
    {
        $formHtml = [];
        $brands = $brandRepository->findAll();
        foreach ($brands as $brand) {
            $form = $this->createForm(BrandType::class, $brand);
            $form->handleRequest($request);
            if ($form->isSubmitted()) {
                dd($brand);
            }
            $formHtml[] = $this->renderView('item/brand/_brandForm.html.twig', [
                'formView' => $form->createView(),
                'brandId' => $brand->getId(),
            ]);
        }
        return $this->render('item/brand/listForm.html.twig', [
            'forms' => $formHtml,
        ]);
    }

Forms are correctly generated but when I submit one of them it returns a entity with the correct submitted data but with the wrong ID (the first one returned by the database).

I tried to figure out how to pass the ID to the POST request but I'm stuck because I can't set ID on the submitted entity. Maybe I'm on the wrong way, but I would be sure that I'm not missing an option to achieve my need like that.

Any suggestion will be welcome ;)

CodePudding user response:

Finally I found the solution. The trick was simply to create named form with ID as name. I use the factory to do that.

Here is the fixed controller :

/**
 * @Route("admin/item/brand/editable-list", name="admin_item_brand_editable-list")
 */
public function editableList(FormFactoryInterface $formFactoryInterface, EntityManagerInterface $em, Request $request, BrandRepository $brandRepository)
{
    $formHtml = [];
    $brands = $brandRepository->findAll();
    foreach ($brands as $brand) {
        $form = $formFactoryInterface->createNamedBuilder($brand->getId(), BrandType::class, $brand)->getForm();
        $form->handleRequest($request);
        if ($form->isSubmitted()) {
            if ($form->get('saveButton')->isClicked()) {
                $em->flush();
                $formHtml[] = $this->renderView('item/brand/_brandForm.html.twig', [
                    'formView' => $form->createView(),
                    'brandId' => $brand->getId(),
                ]);
            } elseif ($form->get('deleteButton')->isClicked()) {
                $em->remove($brand);
                $em->flush();
            } else {
                throw new ErrorException('un bouton doit être clické');
            }
        } else {
            $formHtml[] = $this->renderView('item/brand/_brandForm.html.twig', [
                'formView' => $form->createView(),
                'brandId' => $brand->getId(),
            ]);
        }
    }
    return $this->render('item/brand/listForm.html.twig', [
        'forms' => $formHtml,
    ]);
}
  • Related