How to combine 2 forms in Symfony2

I am trying to create a very simple forum with Symfony2.

My objects: ForumCategory (name, description ...) ForumTopic (category_id, name) ForumPost (isFirstPost, body, topic_id, author_id ...)

When a user tries to create a topic, I want to display only one form on the same page to create a topic and the first message. How:

  • Insert topic name: ...
  • Insert body topic (linked message body): ...

[...]

How can i do this? Is it possible in this case to combine the two forms?

+6
source share
3 answers

Make a type of form containing both of your subforms.

class MergedFormType $builder->add('topic', new TopicFormType()); $builder->add('post', new PostFormType()); 

In your controller, just pass the array to MergedFormType

 public function myAction() $formData['topic'] = $topic; $formData['post'] = $post; $form = $this->createForm(new MergedFormType(), $formData); 
+12
source

Inclusion if you want to combine forms for two objects with a ratio of one or more or one to one; you will need to use the form set extension for the symfony 2 component. for example: where the Task object has many tags

 class TaskType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('description'); $builder->add('tags', 'collection', array('type' => new TagType())); } 

Rendering can be done this way.

 {{ form_start(form) }} <h3>Tags</h3> <ul class="tags"> {# iterate over each existing tag and render its only field: name #} {% for tag in form.tags %} <li>{{ form_row(tag.name) }}</li> {% endfor %} </ul> 

Additional information: http://symfony.com/doc/2.7/cookbook/form/form_collections.html

+1
source

You can also map the same object to multiple merged forms.

  $entity = new Form(); $form = $this->get('form.factory')->create(FormType::class, [ 'form_builder' => $entity, 'submit_builder' => $entity, ]); 

FormType.php

 <?php namespace GenyBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\OptionsResolver\OptionsResolver; use GenyBundle\Entity\Form; class FormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('form_builder', FormBuilderType::class, [ 'data_class' => Form::class, 'label' => false, // Important! ]) ->add('submit_builder', SubmitBuilderType::class, [ 'data_class' => Form::class, 'label' => false, ]) ->add('save', Type\SubmitType::class, [ 'label' => 'geny.type.form.save.label', ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'translation_domain' => 'geny', ]); } } 

FormBuilderType.php

 <?php namespace GenyBundle\Form\Type; use GenyBundle\Base\BaseType; use Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class FormBuilderType extends BaseType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('title', Type\TextType::class, [ 'attr' => [ 'placeholder' => 'geny.type.form.title.placeholder', ], 'empty_data' => $this->get('translator')->trans('geny.type.form.title.default', [], 'geny'), 'label' => 'geny.type.form.title.label', 'required' => true, ]) ->add('description', Type\TextareaType::class, [ 'attr' => [ 'placeholder' => 'geny.type.form.description.placeholder', ], 'empty_data' => null, 'label' => 'geny.type.form.description.label', 'required' => false, ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => 'GenyBundle\Entity\Form', 'translation_domain' => 'geny', ]); } } 

SubmitBuilderType.php

 <?php namespace GenyBundle\Form\Type; use GenyBundle\Base\BaseType; use Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class SubmitBuilderType extends BaseType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('submit', Type\TextType::class, [ 'attr' => [ 'placeholder' => 'geny.type.submit.submit.placeholder', ], 'empty_data' => $this->get('translator')->trans('geny.type.submit.submit.default', [], 'geny'), 'label' => 'geny.type.submit.submit.label', 'required' => true, ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => 'GenyBundle\Entity\Form', 'translation_domain' => 'geny', ]); } } 

Form.php

 <?php namespace GenyBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use JMS\Serializer\Annotation as Serializer; use Symfony\Component\Validator\Constraints as Assert; /** * @ORM\Table(name="geny_form") * @ORM\Entity(repositoryClass="GenyBundle\Repository\FormRepository") * @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT") * @Serializer\ExclusionPolicy("NONE") */ class Form { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue(strategy="AUTO") * @ORM\Id * @Serializer\Exclude */ protected $id; /** * @var string * * @ORM\Column(name="title", type="string", length=128) * @Assert\Length(min = 1, max = 128) * @Serializer\Type("string") */ protected $title; /** * @var string * * @ORM\Column(name="description", type="text", nullable=true) * @Assert\Length(min = 0, max = 4096) * @Serializer\Type("string") */ protected $description; /** * @var ArrayCollection * * @ORM\OneToMany(targetEntity="Field", mappedBy="form", cascade={"all"}, orphanRemoval=true) * @ORM\OrderBy({"position" = "ASC"}) * @Assert\Valid() * @Serializer\Type("ArrayCollection<GenyBundle\Entity\Field>") */ protected $fields; /** * @var string * * @ORM\Column(name="submit", type="text") * @Assert\Length(min = 1, max = 64) * @Serializer\Type("string") */ protected $submit; } 

Result:

result

0
source

Source: https://habr.com/ru/post/952193/


All Articles