简体   繁体   English

Symfony 表单集合渲染

[英]Symfony form collection rendering

I'm using symfony 2.3 I have form with field of type "collection"我正在使用 symfony 2.3 我有一个带有“集合”类型字段的表单

Visualization code in twig:树枝中的可视化代码:

{% for field in form.fields %}
    {{ form_row(field.name) }}
{% endfor %}

Everything work, expect when form.fields is empty.一切正常,期待 form.fields 为空时。 Then nothing is visualized in twig loop, witch is fine.然后在树枝循环中没有任何可视化,女巫很好。 But at the end of the form there is "label" for the element "form.fields".但是在表单的末尾有元素“form.fields”的“标签”。 Only label.只有标签。

Workaround:解决方法:

    {% for field in form.fields %}
        {{ form_row(field.name) }}
    {% endfor %}
    <div class="hidden">
        {{ form_row(form.fields) }}

If there are elements, they will be rendered in the loop.如果有元素,它们将在循环中呈现。 {{ form_row }} will be empty, because all elemets are iterated in the loop above. {{ form_row }} 将为空,因为所有元素都在上面的循环中迭代。 But if form.fields is empty then there is "hidden" (in the div) label.但如果 form.fields 为空,则有“隐藏”(在 div 中)标签。

What I'm missing !?我错过了什么!? Why this is happening !?为什么会这样!?

Hidden div content:隐藏的div内容:

<div class="form-group"><label class="col-sm-2 control-label required">name</label><div class="col-sm-10"><div id="my-id" data-prototype=""></div></div></div>

Builder config:构建器配置:

$builder->add(
    'fieldDataMappers',
    'collection',
    array(
        'type' => new FieldDataType(),
        'allow_add' => true,
        'allow_delete' => true,
        'by_reference' => false,
    )
);

As you have correctly guessed, the Symfony TwigBridge keep track of what is rendered and what is not.正如您正确猜到的,Symfony TwigBridge 会跟踪渲染的内容和未渲染的内容。 This is useful, since there is a function called form_rest(form) , which is especially useful for printing hidden form field, and to prevent the "great jupiter! I forgot to print that field!"这很有用,因为有一个名为form_rest(form)的函数,它对于打印隐藏的表单字段特别有用,并且可以防止“伟大的木星!我忘了打印那个字段!” moments.时刻。 :) You often find form_rest at the end of the form, just before the submit button. :) 您经常会在表单末尾找到form_rest ,就在提交按钮之前。

Also consider that the collection IS a composite form type, which contains a variable list of child form.还要考虑集合是一个复合表单类型,它包含一个子表单的变量列表。 When the for loop is not triggered, since the form type is empty, the call to {{ form_row(form.fields) }} print out the collection form type.for循环没有触发时,由于表单类型为空,调用{{ form_row(form.fields) }}打印出集合表单类型。 By default, this will print (you've guessed it) the collection label and an empty div.默认情况下,这将打印(您已经猜到了)集合标签和一个空的 div。 On the other hand, when the collection is not empty, Symfony will consider the collection as rendered, since all children are already rendered (see FormView::isRendered )另一方面,当集合不为空时,Symfony 会将集合视为已渲染,因为所有子项都已渲染(请参阅FormView::isRendered

You can take a look into Symfony standard theme form_div_layout.html.twig , especially the blocks form_row (which show label printing) and form_widget_compound (the div and the for loop).您可以查看 Symfony 标准主题form_div_layout.html.twig ,尤其是块form_row (显示标签打印)和form_widget_compounddiv和 for 循环)。

So, if you just need to hide the label (quick and dirty, some div are still there), just use:因此,如果您只需要隐藏标签(又快又脏,有些div仍然存在),只需使用:

$builder->add(
    'fieldDataMappers',
    'collection',
    array(
        'type' => new FieldDataType(),
        'label' => false,
        'allow_add' => true,
        'allow_delete' => true,
        'by_reference' => false,
    )
);

Or better, simply output the whole collection widget, without row:或者更好的是,简单地输出整个集合小部件,没有行:

{{ form_widget(form.fieldDataMappers) }}

Or even better, you print the whole collection with:或者更好的是,您可以使用以下方式打印整个系列:

{{ form_row(form.fieldDataMappers) }}

...and then add a Twig theme to customize the collection output with something like (note the name syntax, and the missing form_label call): ...然后添加一个Twig 主题来自定义集合输出,例如(注意名称语法,以及缺少的form_label调用):

{% block collection_row -%}
    <div>
        {{- form_errors(form) -}}
        {{- form_widget(form) -}}
    </div>
    <div class="hidden">Something here?</div>
{%- endblock collection_row %}

Hope this help!希望这有帮助!

{# src/Acme/TaskBundle/Resources/views/Task/new.html.twig #}

{# ... #}

{{ form_start(form) }}
    {# render the task's only field: description #}
    {{ form_row(form.description) }}

    <h3>Tags</h3>
    <ul class="tags">
        {# iterate over each existing tag and render its only field: name #}
        {% for tag in form.tags %}
            <li>{{ form_row(tag.name) }}</li>
        {% endfor %}
    </ul>
{{ form_end(form) }}

{# ... #}

Symfony2 cookbook Symfony2 食谱

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

Also the field of the collection is named fieldDataMappers not field .集合的字段也被命名为fieldDataMappers而不是field

So i think it should be所以我认为应该是

{% for field in form.fieldDataMappers %}
    {{ form_row(field.name) }}
{% endfor %}
    {{ form_label(form.emails) }}
    <ul id="email-fields-list"
        data-prototype="{{ form_row(form.emails.vars.prototype)|e }}"
        data-widget-tags="{{ '<ol></ol>'|e }}"
        data-widget-counter="{{ form.emails|length }}">
        {% for email in form.emails %}
            <ol>
                {{ form_errors(email) }}
                {{ form_row(email) }}
            </ol>
        {% endfor %}
    </ul>
    <button type="button" class="add-another-collection-widget" data-list-selector="#email-fields-list">Add email</button>
    {{ form_widget(form.emails) }}

I just add {{ form_widget(form.emails) }} after block thant handles adding to collection and no more label on the end of form.我只是在块之后添加{{ form_widget(form.emails) }}处理添加到集合并且在表单末尾没有更多标签。

Cheers干杯

I solved this with :我用以下方法解决了这个问题:

{{ form_label(form.collection) }}
{% for element in form.collection %}
    {{ form_widget(element) }}
{% else %}
    {{ form_widget(form.collection) }}
{% endfor %}

(a bit late, I know, but still a problem with Symfony 5) (有点晚了,我知道,但 Symfony 5 仍然存在问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM