我想创建一个由多个问题(不同的实现类)组成的调查。 我很乐意将Survey创建以及所有问题表示为FormType,以便从Symfony Form Component中轻松获得验证和所有好东西。 嵌套described here等表单非常容易。
但现在是棘手的部分:
每个问题都有自己的FormType,并且应该在一个页面上创建和回答(由调查接受者填写)。所以在一页上的所有问题。或多或少,这就像Google表单一样,能够快速地在一个页面上添加新问题,并使用户能够轻松地一次查看所有问题。
我的2个问题是:
我很想听听你的一些想法。
谢谢, 卢卡斯
答案 0 :(得分:4)
使用听众的力量。您可以使用CollectionType
与ResizeListener
使用的流程几乎相同的流程。
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
...
foreach ($data as $name => $value) {
$form->add($name, $this->getTypeByClass($value), array_replace(array(
'property_path' => '['.$name.']',
), $this->options));
}
}
...
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
...
if ($this->allowAdd) {
foreach ($data as $name => $value) {
if (!$form->has($name)) {
// put special value into sub-form to indicate type of the question
$type = $value['type'];
unset($value['type']);
$form->add($name, $type, array_replace(array(
'property_path' => '['.$name.']',
), $this->options));
}
}
}
}
尝试使用allowDelete,allowAdd features实现非常相似的流程。
应该有其他类SurveyData.{items, survey, ...}
与调查的n-1关系,SurveyItem.{answer, ...}
与QuestionAnswer
的n-1关联。在您的结构的基础上应该有书面验证器。
可以使用Valid
约束来触发级联验证。
http://symfony.com/doc/current/reference/constraints/Valid.html
<强>更新强>
如何形成可变部分。
public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($options['allow_add'] && $options['prototyped']) {
// @var ['prototype_name' => '__name__', 'type' => 'question_type']
foreach ($options['prototypes'] as $prototype) {
$prototype = $builder->create($prototype['prototype_name'], $options['type'], $options['options']);
$prototype->add('type', 'hidden', ['data' => $options['type'], 'mapped' => false]);
$prototypes[$options['type']] = $prototype->getForm();
}
$builder->setAttribute('prototypes', $prototypes);
}
...
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars = array_replace($view->vars, array(
'allow_add' => $options['allow_add'],
'allow_delete' => $options['allow_delete'],
));
if ($form->getConfig()->hasAttribute('prototypes')) {
$view->vars['prototypes'] = $form->getConfig()->getAttribute('prototypes')->createView($view);
}
}
现在可以在树枝的form
块中使用原型。
{% for key, prototype in prototypes %}
{% set data_prototypes[key] = form_row(prototype) %}
{% endfor %}
{% set attr = attr|merge({'data-prototypes' : data_prototypes|json_encode })
现在你不需要JS中的ajax请求 - 只需使用原型。
(var collection = $('your_collection')).append(collection.data('prototypes')[question_type].replace(/__name__/g, counter+1));
您已将元素添加到集合中,现在管理员可以填充它并提交表单。其余的工作(将数据映射到课堂)将由Symfony完成。