简体   繁体   English

如何在Symfony2中合并2表单

[英]How to merge 2 form in Symfony2

I'm trying to create a very simple forum with Symfony2. 我正在尝试用Symfony2创建一个非常简单的论坛。

My entities are: ForumCategory (name, description...) ForumTopic (category_id, title) ForumPost (isFirstPost, body, topic_id, author_id...) 我的实体是:ForumCategory(名称,描述......)ForumTopic(category_id,title)ForumPost(isFirstPost,body,topic_id,author_id ......)

When a user try to create a Topic, I want to display only one form in the same page to create a Topic and the first post message. 当用户尝试创建主题时,我想在同一页面中只显示一个表单来创建主题和第一个帖子消息。 Like: 喜欢:

  • Insert topic title: ... 插入主题标题:...
  • Insert topic body (related Post Body): ... 插入主题正文(相关帖子正文):...

[...] [...]

How can I do that? 我怎样才能做到这一点? It's possible merge two form in this case? 在这种情况下,可能合并两种形式?

Make a form type that contains both of your sub forms. 创建一个包含两个子表单的表单类型。

class MergedFormType

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

In your controller just pass an array to MergedFormType 在您的控制器中只需将数组传递给MergedFormType

public function myAction()

    $formData['topic'] = $topic;
    $formData['post']  = $post;

    $form = $this->createForm(new MergedFormType(), $formData);

Incase if you are looking to merge forms for 2 entities with one to many or one to one relationship; 如果您希望将两个实体的表单合并为一对多或一对一关系,请注意; you will need to use form collection extension of symfony 2 component. 您将需要使用symfony 2组件的表单集合扩展。 for eg: where Task entity 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>

Further details: http://symfony.com/doc/2.7/cookbook/form/form_collections.html 更多详情: http//symfony.com/doc/2.7/cookbook/form/form_collections.html

You can also map the same entity to multiple merged forms. 您还可以将同一实体映射到多个合并的表单。

    $entity = new Form();

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

FormType.php 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 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 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 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: 结果:

结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM