widget_attributes和widget_container_attributes有什么区别?

时间:2013-08-16 00:07:27

标签: symfony twig symfony-forms

好的,不好的问题,因为语义上我想我可以通过块名称本身来收集差异。我真正的问题是,当给定元素需要widget_attributeswidget_containter_attributes时,如何控制哪些属性显示为容器和元素。

请考虑以下事项:

<div class="ui-select foo bar baz">
    <select id="abc_hello_worldtype_name" name="abc_hello_worldtype[name]" class="thud grunt">
        ...
    </select>
</div>

我要处理的主要事情是必须在divselect上设置类名。这是出于样式原因以及与行为相关的要求所必需的。

让我感到困惑的主要原因是原始的widget_attributes和widget_container_attributes都使用传入的attr变量。这些变量是否打算一起使用?


我发现自己今天做了类似的事情;只是让我自己的块从原件复制并添加到条件。这一切看起来都太复杂了。我知道我做错了。

{% block choice_widget_collapsed %}
{% spaceless %}
    {% set attr = attr|merge({'class': (attr.class|default('') ~ ' ui-select')|trim}) %}
    <div {{ block('ui_select_container_attributes') }}>
        <select {{ block('ui_select_widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
            {% if empty_value is not none %}
                <option value=""{% if required %} disabled="disabled"{% if value is empty %} selected="selected"{% endif %}{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
            {% endif %}
            {% if preferred_choices|length > 0 %}
                {% set options = preferred_choices %}
                {{ block('choice_widget_options') }}
                {% if choices|length > 0 and separator is not none %}
                    <option disabled="disabled">{{ separator }}</option>
                {% endif %}
            {% endif %}
            {% set options = choices %}
            {{ block('choice_widget_options') }}
        </select>
    </div>
{% endspaceless %}
{% endblock choice_widget_collapsed %}

请注意ui_*div上的select块引用。这些块看起来像:

{% block ui_select_widget_attributes %}
{% spaceless %}
    id="{{ id }}" name="{{ full_name }}"{% if read_only %} readonly="readonly"{% endif %}{% if disabled %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}
    {% for attrname, attrvalue in attr %}{% if attrname in ['placeholder', 'title'] %}{{ attrname }}="{{ attrvalue|trans({}, translation_domain) }}" {% elseif attrname == 'class' %} class="foopa {{ attrvalue|replace({'ui-select':''}) }}" {% else %}{{ attrname }}="{{ attrvalue }}" {% endif %}
    {% endfor %}
{% endspaceless %}
{% endblock ui_select_widget_attributes %}

{% block ui_select_container_attributes %}
{% spaceless %}
    {% if id is not empty %}id="{{ id }}" {% endif %}
    {% for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
{% endspaceless %}
{% endblock ui_select_container_attributes %}

1 个答案:

答案 0 :(得分:1)

当表单字段呈现为单个表单输入(文本输入,选择,复选框...)时,将使用widget_attributes。当它呈现为输入集合(表单,多个复选框,多个输入......)时,widget_container_attributes用于输入周围的容器(主要是div)。所以不,它们不打算同时使用。

两个块之间的区别在于widget_attributes呈现特定于表单的属性(&#34;值&#34;,&#34; name&#34; ...)而widget_container_attributes仅呈现通用HTML属性。

如果你想添加额外的标记超出&#34; attr&#34;选项,您最好的选择是从表单主题中复制相应的块(例如&#34; choice_widget_collapsed&#34;),将其粘贴到您的模板中,重命名该块以使您的元素的ID与前导下划线匹配( &#34; _&#34;)和#34;小部件&#34;后缀(例如,如果您的元素的ID是&#34; form_my_element&#34;,该块将被调用&#34; _form_my_element_widget&#34;)并修改模板中的标记。

{% block body %}
...
{{ form(form) }}
...
{% endblock %}

{% block _form_my_element_widget %}
... modified version of the "choice_widget_collapsed" markup ...
{% endblock %}