Symfony3 - 如何呈现嵌入式表单集合

时间:2017-12-30 14:24:26

标签: symfony collections twig display symfony3.x

我还没有找到手动渲染包含集合的表单的解决方案。 这是我在twig中的代码:

<ul id="document-fields-list" data-prototype="{{ form_widget(formulario.documentos.vars.prototype)|e }}">
    <div><button class="pull-right" href="#" id="add-another-document">Agregar documento</button></div>
    {% for documento in formulario.documentos %}
        <li>
            {{ form_label(documento) }}
            {{ form_widget(documento) }}
            <a href="#" class="remove-item">Eliminar</a>
        </li>
    {% endfor %}
</ul>

1 个答案:

答案 0 :(得分:1)

<强> FormType

在您的情况下,我们需要为PersonaDocumento创建formType。想象一下,这个实体有字段documentName:

class PersonaDocumentoType extends AbstractType
{
    /**
     * @param FormBuilderInterface  $builder
     * @param array                 $options
     * @SuppressWarnings(unused)
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('documentName', TextType::class, [
                'label'                 => false,
                'translation_domain'    => 'messages'
            ])
        ;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'app_persona_documento_type';
    }

    /**
     * @return null|string
     */
    public function getBlockPrefix()
    {
        return 'app_persona_documento';
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'            => PersonaDocumento::class,
            'csrf_protection'       => true,
            'validation'            => true,
        ));
    }
}

包含集合的表单

考虑您实体Formulario。它与PersonaDocumento有一个OneToMany关系。表格将是:

class FormularioFormType extends AbstractType
{
    /**
     * @param FormBuilderInterface  $builder
     * @param array                 $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ...

        $builder
            ->add('documentos', CollectionType::class, [
                'entry_type'    => PersonaDocumentoType::class,
                'entry_options' => [
                    'label'         => false,
                ],
                'label'         => false,
                'allow_add'     => true,
                'allow_delete'  => true,
                'by_reference'  => false,  // Very important thing!
            ])
        ;
    }

    // ...
}

收集小工具

我们有一个表单( FormularioFormType ),其中包含类型为 PersonaDocumentoType 的小表单集合。

您可以使用标准小部件在文件中创建的新小部件,以及file is fields.html.twig的名称:path_to_your_project/src/AppBundle/Resources/views/Form/fields.html.twig

块的名称为app_persona_documento_widget

因此,fields.html.twig

的例子
{% trans_default_domain 'messages' %}

{% block app_persona_documento_widget %}
    {% spaceless %}
        <div class="form-group" {{ block('widget_container_attributes') }}>
            <div class="col-sm-12">
                {{ form_widget(form.name, {'attr' : { 'placeholder' : 'app.form.label.name'|trans , 'class' : 'form-control' }}) }}
            </div>
        </div>
    {% endspaceless %}
{% endblock app_persona_documento_widget %}

还要注意&#34; app_persona_documento_widget&#34; - 从您的getBlockPrefix()汇总的PersonaDocumentoType加上字符串&#34; _widget&#34;

在config.yml中注册新表单主题

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
    form_themes:
        # other form themes
        # ...
        - 'AppBundle:Form:fields.html.twig'

以父表单呈现集合

            {{ form_start(formulario_form) }}
                <div class="form-group">
                    <label for="" class="col-sm-2 control-label">
                        Label
                    </label>
                    <div class="col-sm-10 documentos" data-prototype="{{ form_widget(formulario_form.documentos.vars.prototype)|e('html_attr') }}">
                        {% for document in formulario_form.documentos %}
                            <div>
                                {{ form_widget(document) }}
                            </div>
                        {% endfor %}
                    </div>
                </div>
                <span>
                    {{ form_errors(formulario_form) }}
                </span>
                {#  Here you can add another fields of form   #}
            {{ form_end(formulario_form) }}

当然,您还需要按钮:一个&#34;添加另一个文档&#34; 按钮和&#34;删除&#34; 按钮#34;&这份执行#34;项目。

Symfony文档表明我们为此目的使用JavaScript。 您可以阅读更多here in official docs

您还可以安装Ninsuo/symfony-collection - 一个jQuery插件,用于管理从Symfony集合中添加,删除和移动元素