【问题标题】:How to merge 2 form in Symfony2如何在 Symfony2 中合并 2 个表单
【发布时间】:2013-08-21 11:14:32
【问题描述】:

我正在尝试使用 Symfony2 创建一个非常简单的论坛。

我的实体是: ForumCategory(名称、描述...) 论坛主题(category_id,标题) ForumPost (isFirstPost, body, topic_id, author_id...)

当用户尝试创建主题时,我想在同一页面中仅显示一个表单来创建主题和第一条发布消息。喜欢:

  • 插入主题标题:...
  • 插入主题正文(相关的帖子正文):...

[...]

我该怎么做?这种情况下可以合并两种形式吗?

【问题讨论】:

    标签: forms symfony entities


    【解决方案1】:

    创建一个包含两个子表单的表单类型。

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

    在您的控制器中,只需将一个数组传递给 MergedFormType

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

    【讨论】:

    • 我已完成此操作,但当我提交嵌套表单之一中的字段时,出现错误“此表单不应包含额外字段”。有什么想法吗?
    • 使用 symfony/form 3.* 我在 MergedFormType 中得到 Expected argument of type "string"。任何想法如何解决这个问题?
    • 你检查过文档吗? S3 不再支持传递表单类型的实例。几项重大的形式更改之一。
    • 对于 symfony3 看这里:stackoverflow.com/questions/35254110/…
    • @Cerad 你能帮帮忙吗? @ 987654322@,我正在做你建议的事情......但对我没有用。 $formData 无法识别。
    【解决方案2】:

    如果您希望合并具有一对多或一对一关系的 2 个实体的表单;您将需要使用 symfony 2 组件的表单集合扩展。例如:任务实体有很多标签

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

    可以通过这种方式进行渲染

    {{ 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>
    

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

    【讨论】:

      【解决方案3】:

      您还可以将同一实体映射到多个合并表单。

          $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;
      }
      

      结果:

      【讨论】:

        猜你喜欢
        • 2022-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多