Symfony2静态表单集合标签

时间:2014-05-19 18:01:25

标签: forms symfony

我正在查看这部分文档:

http://symfony.com/doc/current/cookbook/form/form_collections.html

除了我的情况,每个tag都是question,每个问题都有一个唯一的标签。

如何为集合表单创建唯一标签?

QuestionType:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class QuestionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('Answer', 'choice' array(
        'choices' => array(
                  '' => 'select one',
                  'yes',
                  'no')
        ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\AcmeBundle\Entity\Question\Question',
        ));
    }

    public function getName()
    {
        return 'question';
    }
}

问题集:

class BriefQuestionaireType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('Questions', 'collection', array(
            'type' => new QuestionType()
            )
        );
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\AcmeBundle\Entity\Question\Questionaire',
        ));
    }

    public function getName()
    {
        return 'briefquestionaire';
    }
}

我希望能够做到这样的事情:

$builder->add('Questions', 'collection', array(
                'label' => 'Q1:Have you ever...?', //I'd like to use unique but static questions so that I can reuse the questions again later.`
                'type' => new QuestionType()
                )
            );


$builder->add('Questions', 'collection', array(
                'label' => 'Q2:Have you also...?', //I'd like to use unique but static questions so that I can reuse the questions again later.`
                'type' => new QuestionType()
                )
            );

但是,上面的内容会覆盖以前的标签。因此只显示标签Q2:Have you also...?

希望现在更清楚了,当我说我想要有选择是/否的独特标签(只是静态问题)时,我的意思就是这样。

2 个答案:

答案 0 :(得分:2)

您只需要一个收集字段。 "问题"绑定到表单的数据中的数组将确定显示多少个QuestionType字段。 E.g ...

// Acme/DemoBundle/Controller/DefaultController.php

// ...

$data = array(
    'Questions' => array(
        array('Answer' => 'First Answer'),
        array('Answer' => 'Second Answer'),
        array('Answer' => 'Third Answer')
    );
);

$form = $this->createForm(new BriefQuestionaireType(), $data);

// ...

问题是,当所有问题字段的选项完全相同时,如何为每个问题字段显示唯一标签?

前几天我遇到了这个问题并解决了这个问题。

// Acme/DemoBundle/Form/LabelGenerator.php    

class LabelGenerator{

    private $labels;

    public function __construct(array $labels){
        $this->labels = $labels;
    }        

    public function __toString(){
        $keyValue = each($this->labels);
        return $keyValue['value'];
    }

}

// Acme/DemoBundle/Form/Type/BriefQuestionaireType.php

// ...

public function buildForm(FormBuilderInterface $builder, array $options) {

    $labelGenerator = new LabelGenerator(array(
        'Q1: What is the first question?',
        'Q2: What is the second question?',
        'Q3: What is the third question?'
    ));

    $builder->add('Questions', 'collection', array(
        'type' => new QuestionType(),
        'options' => array(
            'label' => $labelGenerator    
        )
    ));

}

// ...

每次表单主题呈现一个Question标签时,LabelGenerator都会返回数组中的下一个值。

我建议您添加" question_labels"带有setDefaultOptions()的BriefQuestionaireType表单的选项。然后你可以将它们传递给这样的集合。

// Acme/DemoBundle/Controller/DefaultController.php

// ...

$form = $this->createForm(new BriefQuestionaireType(), $data, array(
    'question_labels' => $labels
));

// ...

// Acme/DemoBundle/Form/Type/BriefQuestionaireType.php

// ...

public function setDefaultOptions(OptionsResolverInterface $resolver) {

    $resolver->setRequired(array('question_labels'));

}

public function buildForm(FormBuilderInterface $builder, array $options) {

    $labelGenerator = new LabelGenerator($options['question_labels']);

    $builder->add('Questions', 'collection', array(
        'type' => new QuestionType(),
        'options' => array(
            'label' => $labelGenerator    
        )
    ));

}

// ...

或者,如果您想从问题实体中获取标签,您可以这样做。

// Acme/DemoBundle/Form/Type/BriefQuestionaireType.php

// ...

public function buildForm(FormBuilderInterface $builder, array $options) {

    $labels = array();
    foreach($builder->getData()->getQuestions() as $question){
        $labels[] = $question->getLabel();
    }

    $labelGenerator = new LabelGenerator($labels);

    $builder->add('questions', 'collection', array(
        'type' => new QuestionType(),
        'options' => array(
            'label' => $labelGenerator    
        )
    ));

}

// ...

编辑:您需要使用适当数量的问题实体预先填写问题,否则您只会收集一个空集。

答案 1 :(得分:0)

如果我对你想达到的目标是对的,我在一周前回答了类似的问题:

<强> How to pass entity atribute value to form Symfony2?

基本上,解决方案依赖于FormEvent来将数据传达给Form并构建它的字段 dinamically