2013-08-21 36 views
6

Tôi đang cố tạo một diễn đàn rất đơn giản với Symfony2.Cách kết hợp 2 biểu mẫu trong Symfony2

thực thể của tôi là: ForumCategory (tên, mô tả ...) ForumTopic (category_id, tiêu đề) ForumPost (isFirstPost, cơ thể, topic_id, AUTHOR_ID ...)

Khi người dùng cố gắng tạo ra một Chủ đề, tôi muốn chỉ hiển thị một biểu mẫu trong cùng một trang để tạo Chủ đề và bài đăng đầu tiên. Giống như:

  • Chèn tiêu đề chủ đề: ...
  • Insert chủ đề cơ thể (liên quan đến bài viết Body): ...

[...]

Làm thế nào tôi có thể làm điều đó ? Có thể hợp nhất hai hình thức trong trường hợp này?

Trả lời

12

Tạo loại biểu mẫu chứa cả hai biểu mẫu phụ của bạn.

class MergedFormType 

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

Trong điều khiển của bạn chỉ cần vượt qua một mảng để MergedFormType

public function myAction() 

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

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

Tôi đã làm điều này, nhưng tôi nhận được lỗi "Hình thức này không nên chứa trường bổ sung" khi tôi gửi các lĩnh vực đó là một trong các hình thức lồng nhau. bất kỳ ý tưởng? – StampyCode

+1

Sử dụng symfony/form 3. * Tôi nhận được 'Đối số dự kiến ​​của kiểu" chuỗi "' trong MergedFormType.Bất kỳ ý tưởng làm thế nào để giải quyết điều này? – Keloo

+0

Bạn đã kiểm tra tài liệu chưa? S3 không còn hỗ trợ truyền một thể hiện của một loại biểu mẫu. Một trong những thay đổi hình thức quan trọng. – Cerad

1

Trong trường hợp nếu bạn đang tìm kiếm để hợp nhất các hình thức cho 2 đơn vị với một đến nhiều hoặc 1-1 mối quan hệ; bạn sẽ cần sử dụng phần mở rộng của form symfony 2. cho ví dụ: nơi công tác tổ chức có nhiều Thẻ

class TaskType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('description'); 

     $builder->add('tags', 'collection', array('type' => new TagType())); 
    } 

Rendering thể được thực hiện theo cách này

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

Thông tin chi tiết: http://symfony.com/doc/2.7/cookbook/form/form_collections.html

0

Bạn cũng có thể lập bản đồ cùng một thực thể với nhiều hình thức sáp nhập.

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

Kết quả:

result

Các vấn đề liên quan