Symfony2:如何嵌入带有变量标签的表单集合?

时间:2012-11-15 15:11:37

标签: forms symfony-2.1

感谢this help我可以创建一个带有变量标签的表单。 现在我想创建一个这样的表单集合,但我不能这样做。

准确地说:我有一个MyField类:

class MyField {
    protected label;
    protected userAnswer;

    public function setLabel($label){...}
    public function getLabel(){...}
    public function setUserAnswer($answer){...}
    public function getUserAnswer(){...}
}

我还有一个MyFieldType类:

class MyFieldType extends AbstractType{
    public function buildForm(FormBuilderInterface $builder, array $options){
        $myField = $options['myField'];
        $builder->add('userAnswer', 'text', array('label' => $myField->getLabel()));
    }

    public function getDefaultOptions(array $options){
        return array('data_class' => '...\MyField',
                        'myField' => null);
    }
}

并且,在控制器中:

public function MyAction(Request $request){
    ...
    $myField = new MyField();
    ...
    $form = $this->createForme(new MyFieldType(), $myField, array('myField' => $myField));
    ...
}

尽管如此,字段标签是$ myField-> label。

现在我想创建一个包含多个MyField的表单:我有一个MyForm类

class MyForm {
    protected myFields; // array of MyField
    public function setMyFields...
    public function getMyFields...
    public function addAField...
}

我仍然希望字段标签为$ myField->标签。那么,如何定义MyFormType?
我试过像:

class MyFormType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options){
        $myFields = $options['myFields'];
        $builder->add('myFields', 'collection',
                array('type' => new MyFieldType(),
                    'options' => array('myField' => $myFields[0])));
    }

它有效(当然所有字段都有相同的标签,我不希望如此),但我无法想象如何为每个MyFieldType提供自己的MyField ...

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我会创建这两种类型:

class MyFormType extends AbstractType {

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

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




class MyFieldType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options){

        $builder->add('label', 'text');
    }

希望有所帮助

答案 1 :(得分:0)

我找到了一种方法来做我想做的事(感谢nass600的回答和我的回复): 我创建了一种新类型的字段(参见http://symfony.com/en/doc/current/cookbook/form/create_custom_field_type.html),如下所示:

class LabelType extends AbstractType{
    public function setDefaultOptions(OptionsResolverInterface $resolver){
    }

    public function getParent(){
        return 'text';
    }

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

然后,我更改了MyFieldType:

class MyFieldType extends AbstractType{
    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder->add('label', new LabelType())
                ->add('userAnswer', 'text');
    }

    public function getDefaultOptions(array $options){
        return array('data_class' => '...\MyField')
    }
}

我还创建了一个fields.html.twig,就像在Symfony cookbook中解释的一样,只是:

{% block label_widget %}
  {{ value }}
{% endblock %}

现在,在我的myForm.html.twig中:

...
{% for field in form.myFields %}
{% form_widget(field.label) %}
{% form_widget(field.userAnswer) %}
...

适用于:

class MyFormType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options){
        $myFields = $options['myFields'];
        $builder->add('myFields', 'collection',
                array('type' => new MyFieldType()));
    }
...

再见