我正在尝试用Symfony2创建一个非常简单的论坛。
我的实体是: ForumCategory(名称,描述......) ForumTopic(category_id,title) ForumPost(isFirstPost,body,topic_id,author_id ...)
当用户尝试创建主题时,我想在同一页面中只显示一个表单来创建主题和第一个帖子消息。像:
[...]
我该怎么做?在这种情况下可以合并两种形式吗?
答案 0 :(得分:14)
制作包含两个子表单的表单类型。
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);
答案 1 :(得分:1)
如果您希望将两个实体的表单合并为一对多或一对一关系,请注意;您将需要使用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
答案 2 :(得分:0)
您还可以将同一实体映射到多个合并的表单。
$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;
}
结果: