I have a very simple form with 2 fields, all I want to do is a button where the user could duplicate this form to add multiple entries in one batch.
What i would like to do (I can’t integrate images yet, sry..)
I’m not sure on how to integrate this, I found some documentation about forms collections but i’m not sure if it fits to my needs, plus it was for Symfony 2, i’m using the latest version (Symfony 5)
I thought I could add my button with href='#?duplicateForm=1'
and handle that with the controller & the type but that does not seem to be a proper solution to me… Bad idea to throw a user input in a for
statement.
My Type class:
The form is different depending on the current user role, the admins have more fields.
class NetworkFolderAccessType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { if ($options['type'] == 'ADMIN_FORM'){ $builder ->add('userId', EntityType::class, [ 'class' => User::class, 'choice_label' => function ($user) { return $user->getNom() . ' ' . $user->getPrenom() .' ('. $user->getUsername().')'; }, 'label'=>'Demandeur', 'attr'=> [ 'class'=>'form-control' ] ]) ->add('validated',ChoiceType::class,[ 'expanded'=>false, 'multiple'=>false, 'choices'=>['Oui'=>true,'Non'=>false], 'label'=>'Validé par le responsable', 'attr'=> [ 'class'=>'form-control' ], 'choice_attr'=> [ 'class'=>'checkbox-inline' ] ]); } if($options['type'] == 'USER_FORM' || $options['type'] == 'ADMIN_FORM'){ $builder ->add('dataPath',TextType::class,[ 'attr'=> [ 'class'=>'form-control' ], 'label'=>'Chemin d'accès' ]) ->add('rights', ChoiceType::class, [ 'choices' => [ 'Lecture' => 'read', 'Écriture' => 'write', 'Lecture & Écriture' => 'readwrite', ], 'expanded' => false, 'multiple' => false, 'label'=>'Droits d'accès', 'attr' => ['class' => 'form-control'], ]) ; } } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => NetworkFolderAccess::class, 'type'=>'USER_FORM' ]); } }
My controller :
/** * @Route("/new", name="network_folder_access_new", methods={"GET","POST"}) * @IsGranted("ROLE_USER") */ public function new(Request $request): Response { $networkFolderAccess = new NetworkFolderAccess(); if ($this->isGranted('ROLE_ADMIN')) $form = $this->createForm(NetworkFolderAccessType::class, $networkFolderAccess, ['type'=>'ADMIN_FORM']); elseif ($this->isGranted('ROLE_USER')) $form = $this->createForm(NetworkFolderAccessType::class, $networkFolderAccess, ['type'=>'USER_FORM']); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $entityManager = $this->getDoctrine()->getManager(); $networkFolderAccess->setDateDemand(new DateTime()); if ($this->IsGranted('ROLE_USER') && !$this->isGranted('ROLE_ADMIN')) $networkFolderAccess->setUserId($this->security->getUser()); $entityManager->persist($networkFolderAccess); $entityManager->flush(); return $this->redirectToRoute('network_folder_access_index'); } return $this->render('network_folder_access/new.html.twig', [ 'network_folder_access' => $networkFolderAccess, 'form' => $form->createView(), ]); }
Advertisement
Answer
Did you had a look on these tutorials on symfonyCast ? It would fit your needs perfectly (from chapter 18 to the end)
It will show you how to use the OneToMany relation, the form prototyping and the Collection type to add and/or delete embeded forms.