我正在使用Symfony 2构建一个应用程序,其中一个页面包含一个大型表单,其中有许多固定字段,但也有许多字段,其存在和数量完全取决于从DB获取的相关数据。更具体地说,表单提出了许多问题,这些问题本身来自数据库,具有不同的文本和id。答案需要存储在数据库中,并链接到问题。
我已经阅读了Symfony如何处理表单(基本Symfony表单),包括表单对象和支持它的数据对象之间的关系,从表单对象创建字段,以及根据应用于表单对象的规则验证输入。
因为我不想要一个固定的表单对象,我看了看你是如何动态修改表单(动态Symfony表单),但那里的例子似乎是关于选择是否显示某些预定义字段,或控制字段中的选项,而不是从头开始完全生成新的字段,这是我想要的。
我看了一下关于数据转换器的Symfony页面,它似乎是相关的,但我不太明白它将如何帮助我。它们似乎更多的是将表单对象映射到实体,而不是将复杂的表单提交映射到表单对象。
我确实看到了这个SO的答案,在那里的对象支持的形式对象只是一个数组,这似乎也相关:我认为也许答案是生成一些匿名对象与动态字段,然后使表单,但我不知道我如何设置Symfony验证它,我的形式是不完全不同的每次,所以不需要完全匿名。
使用Symfony 2实现这一目标的最佳方法是什么?理想情况下,不放弃框架的优点,如易于验证等?
我以前没有听说过Symfony表单集合,看起来这可能会做我想要的-在我的情况下,每个问题将映射到一个单独的子表单对象。你的问题很广泛,但这可能有助于集中注意力。
我有一个DynamicFormType,它可以根据配置项数组向表单添加元素。
class DynamicFormType extends AbstractType
{
protected $name;
protected $items;
public function getName() { return $this->name; }
public function __construct($name, $items)
{
$this->name = $name;
$this->items = $items;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
foreach($this->items as $name => $item)
{
switch($item['type'])
{
case 'radio':
$attr = array('class' => 'radio-medium');
$builder->add($name,'choice',array(
'label' => $item['label'],
'required' => false,
'attr' => $attr,
'empty_value' => false,
'expanded' => true,
'multiple' => false,
'choices' => $item['choices'],
));
break;
case 'select':
$attr = array();
$builder->add($name,'choice',array(
'label' => $item['label'],
'required' => false,
'attr' => $attr,
'empty_value' => false,
'expanded' => false,
'multiple' => false,
'choices' => $item['choices'],
));
break;
case 'text':
$attr = array();
if (isset($item['size'])) $attr['size'] = $item['size'];
$builder->add($name,'text',array(
'label' => $item['label'],
'required' => false,
'attr' => $attr,
));
break;
case 'textarea':
$attr = array();
if (isset($item['rows'])) $attr['rows'] = $item['rows'];
if (isset($item['cols'])) $attr['cols'] = $item['cols'];
$builder->add($name,'textarea',array(
'label' => $item['label'],
'required' => false,
'attr' => $attr,
));
break;
case 'collection':
$dynamicType = new DynamicFormType($name,$item['items']);
$builder->add($name,$dynamicType,array(
'label' => false,
'required' => false,
));
break;
}
}
return; if ($options);
}
}
我相信您可以看到items数组是如何用于创建表单元素的。在我的应用程序中,我使用这个:
$basicType = new DynamicFormType('basic',$project->getPlan());
$builder->add('basic',$basicType, array('label' => false));
$project->getPlan()返回items数组,其中描述了我想要添加的各种元素。
希望您可以从这样的东西开始,并找出需要从数据结构中添加哪些元素。我在这里不需要验证,但是一旦事情开始工作,向元素添加约束信息应该很容易。
好的,最后我想要的不是一个真正的动态表单(但感谢@Cerad的代码),而是一个使用集合,其中某些子表单项的数量是可变的。
所以我基本上是按照Symfony文档关于集合的