Symfony表单集合渲染

时间:2015-05-22 14:09:58

标签: php forms symfony twig symfony-forms

我正在使用symfony 2.3 我的表格类型为#34;集合"

树枝中的可视化代码:

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

当form.fields为空时,一切正常。 然后在树枝循环中没有任何可视化,女巫很好。 但在表格的最后有标签"标签"对于元素" form.fields"。只有标签。

解决方法:

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

如果有元素,它们将在循环中呈现。 {{form_row}}将为空,因为所有元素都在上面的循环中迭代。 但是如果form.fields为空,那么就会隐藏&#34; (在div中)标签。

我失踪了什么!为什么会这样?!

隐藏的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,
    )
);

4 个答案:

答案 0 :(得分:3)

正如您已经正确猜到的那样,Symfony TwigBridge会跟踪渲染的内容和不渲染的内容。这很有用,因为有一个名为form_rest(form)的函数,它对打印隐藏的表单字段特别有用,并且可以防止木星!我忘了打印那个字段!&#34;时刻。 :)您经常在表单末尾找到form_rest,就在提交按钮之前。

还要考虑集合是一种复合形式类型,它包含子表单的变量列表。当未触发for循环时,由于表单类型为空,因此对{{ form_row(form.fields) }}的调用将打印出集合表单类型。默认情况下,这将打印(您已经猜到)收集标签和空div。另一方面,当集合不为空时,Symfony会将集合视为已渲染,因为所有子集都已渲染(请参阅FormView::isRendered

您可以查看Symfony标准主题form_div_layout.html.twig,尤其是块form_row(显示标签打印)和form_widget_compounddiv和for循环)

所以,如果你只是需要隐藏标签(快速和脏,有些div仍在那里),只需使用:

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

或者更好的是,只需输出整个集合小部件,而不是行:

{{ form_widget(form.fieldDataMappers) }}

或者甚至更好,您使用以下方式打印整个集合:

{{ form_row(form.fieldDataMappers) }}

...然后添加Twig theme以自定义集合输出(请注意名称语法和缺少的form_label调用):

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

希望这有帮助!

答案 1 :(得分:1)

{# 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

  

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

此外,该集合的字段名为fieldDataMappers而不是field

所以我认为它应该是

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

答案 2 :(得分:0)


            for batch_index, mask_batch in enumerate(mask):
                mask_len = torch.sum(mask_batch).int()

                if mask_len == 0:
                    side_input = torch.zeros((max_inp_len, side_input.shape[1])).to(mask.device)
                else:

                    m_nonzero = mask_batch.nonzero().flatten()
                    first_nonzero = m_nonzero[0]
                    last_nonzero = m_nonzero[-1]

                    if side == 'left':
                        end_index = first_nonzero - 1
                        start_index = 0
                    elif side == 'right':
                        start_index = last_nonzero + 1
                        end_index = inputs[batch_index].size(1)

                    side_input = inputs[batch_index][start_index:end_index]

                    if end_index - start_index < max_inp_len:
                        pad_zeros = torch.zeros(
                            (max_inp_len - side_input.shape[0], side_input.shape[1])).to(mask.device)
                        if side == 'left':
                            side_input = torch.cat((pad_zeros, side_input), 0)
                        elif side == 'right':
                            side_input = torch.cat((side_input, pad_zeros), 0)

                side_inputs.append(side_input)

        return torch.stack(side_inputs)

我只是在块要处理添加到集合中之后添加 {{ 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) }} ,并且在表单末尾不再添加标签。

欢呼

答案 3 :(得分:0)

我解决了这个问题:

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

(我知道有点晚了,但 Symfony 5 仍然存在问题)