NoobieNoob
NoobieNoob

Reputation: 149

Symfony submit multiple related forms

I'm looking to create an CRUD with multiple Entites and so multiple forms. A want to create a Site, each site on creation need to have 1 adresse, each adress need 1 City, each city need 1 Country Relation

So I have a Controller where I called my Type

/**
    * @Route("admin/sites/new", name="admin.sites.new")
    * @param Request $request
    * @return RedirectResponse|Response
    */
   public function new (Request $request)
   {
       $site = new Site();
       $adresse = new Adresse();
       $ville = new Ville();
       $pays = new Pays();
       $form = $this->createForm(SiteType::class, $site);
       $form2 = $this->createForm(AdresseType::class, $adresse);
       $form3 = $this->createForm(VilleType::class, $ville);
       $form4 = $this->createForm(PaysType::class, $pays);
       $form->handleRequest($request);
       $form2->handleRequest($request);
       $form3->handleRequest($request);
       $form4->handleRequest($request);

       if ($form->isSubmitted() && $form->isValid()
           && $form2->isSubmitted() && $form2->isValid()
           && $form3->isSubmitted() && $form3->isValid()
           && $form4->isSubmitted() && $form4->isValid()){
           $this->em->persist($site);
           $this->em->persist($adresse);
           $this->em->persist($ville);
           $this->em->persist($pays);
           $this->em->flush();
           $this->addFlash('success', 'Site crée avec succès');
           return $this->redirectToRoute('admin.sites.index');
       }
       return $this->render('admin/sites/create.html.twig', [
           'site' => $site,
           'adresse' => $adresse,
           'ville' => $ville,
           'pays' => $pays,
           'form' => $form->createView(),
           'form2' => $form2->createView(),
           'form3' => $form3->createView(),
           'form4' => $form4->createView(),
       ]);
   }

and a Twig to generate the view.

    <div class="row">
        <div class="col s12 m12 l12">
            <div class="card-panel ">
                <div class="row">

                    {{ form_start(form) }}
                        {{ form_widget(form) }}


                    {{ form_start(form2) }}
                    {{ form_widget(form2) }}

                    {{ form_start(form3) }}
                    {{ form_widget(form3) }}

                    {{ form_start(form4) }}
                    {{ form_widget(form4) }}

                    <button class="btn s12 m6 l3">{{ button|default('Enregister') }}</button>
                    {{ form_end(form) }}{{ form_end(form2) }}{{ form_end(form3) }}{{ form_end(form4) }}
                </div>
            </div>
        </div>
    </div>

My question is the next, how when i will create my Site, I could link the site_id and the address_id and so the adress_id and the city_id, the city_di and the country _id ? without separate my forms ? I mean when I press the button the relation will be create correctly.

Thanks for you help.

Upvotes: 0

Views: 66

Answers (2)

stephan.mada
stephan.mada

Reputation: 1130

This is how you should and could achieve this : You should use embeded form How to Embed Forms

You simply create form types for your entities : SiteType, AdresseType, VilleType, PaysType and embed them like the following

// in SiteType
    //....
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder
             //...
             ->add('adresse', AdresseType::class)
         ;
    }
// in AdresseType
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder
             //...
             ->add('ville', VilleType::class)
         ;
    }
// in VilleType
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder
             //...
             ->add('pays', PaysType::class)
         ;
    }

Finally in your controller, all you have to do is to create

   /**
    * @Route("admin/sites/new", name="admin.sites.new")
    * @param Request $request
    * @return RedirectResponse|Response
    */
   public function new (Request $request)
   {
       $site = new Site();
       $form = $this->createForm(SiteType::class, $site);
       $form->handleRequest($request);

       if ($form->isSubmitted() && $form->isValid()
           $this->em->persist($site);
           $this->em->flush();
           $this->addFlash('success', 'Site crée avec succès');

           return $this->redirectToRoute('admin.sites.index');
       }

       return $this->render('admin/sites/create.html.twig', [
           'site' => $site,
           'adresse' => $adresse,
           'ville' => $ville,
           'pays' => $pays,
           'form' => $form->createView(),
       ]);
   }

And the corresponding twig is :

    <div class="row">
        <div class="col s12 m12 l12">
            <div class="card-panel ">
                <div class="row">
                    {{ form_start(form) }}
                        {{ form_widget(form) }}

                        <button class="btn s12 m6 l3">{{ button|default('Enregister') }}</button>
                    {{ form_end(form) }}
                </div>
            </div>
        </div>
    </div>

Note that in order for it to work, you need to use cascade inside your entity doctrine metadata, like so :

/**
 * @ORM\OneToOne(targetEntity="AppBundle:Adresse", cascade={"all"})
 */
private $adresse;

Upvotes: 2

Bernard Pagoaga
Bernard Pagoaga

Reputation: 1396

You should use embed forms : https://symfony.com/doc/current/form/embedded.html.

Upvotes: 0

Related Questions