Symfony2/Twig - 遍历 select 个选项

Symfony2/Twig - iterate over select options

显示select字段的通常方式是调用

{{ form_row(form.doctor_service_id, {'attr':{'class':'form-control'}}) }}

我想做两件事:

  1. 检查这个字段是否真的是一个select字段
  2. 迭代每个选项(值、名称)。我知道 twig 迭代器是如何工作的,我只是不知道如何访问 select 选项并将它们转换为它。
  1. 您可以使用 twig 扩展来添加 twig 'instanceof' 运算符。如果您不熟悉创建树枝扩展,请参阅 How to Write a Custom Twig Extension in the Symfony docs. There is a gist which gives an example of a Twig extension that implements an instanceof operator。然后检查字段是否为 select 字段使用:

      {% if value is instanceof('ChoiceType') %}
    
  2. 这并不像您想象的那么简单,因为选择字段有太多选项。在 Symfony 中,表单主题决定了如何将各种字段类型呈现为 html。默认表单主题在 form_div_layout.html.twig. It takes about 50 lines of code to render a choice field taking account of all the options, covered by the blocks choice_widget, choice_widget_expanded, choice_widget_collapsed and choice_widget_options. You could pick out the bits you need based on the options you have set for your choice field and paste them into your twig template but then setting choice options in the form class wouldn't have any affect. The correct way to custom render your choice options (*assuming the select is not expanded) is to override the choice_widget_options block from the form theme. Form Customization 中,它本身就是一个主题,但最简单的方法是在你的 twig 模板中一次性覆盖该块,然后修改它以满足你的需要,例如

    {% extends '::base.html.twig' %}
    
    {% form_theme form _self %}
    
    {%- block choice_widget_options -%}
        {% for group_label, choice in options %}
            {%- if choice is iterable -%}
                <optgroup label="{{ choice_translation_domain is sameas(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
                    {% set options = choice %}
                    {{- block('choice_widget_options') -}}
                </optgroup>
            {%- else -%}
                {% set attr = choice.attr %}
                <option value="{{ choice.value }}" {{ block('attributes') }}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is sameas(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
            {%- endif -%}
        {% endfor %}
    {%- endblock choice_widget_options -%}
    
    {% block content %}
        {# ... render the form #}
    
        {{ form_row(form.doctor_service_id, {'attr':{'class':'form-control'}}) }}
    {% endblock %}
    

如果您不需要自定义选择字段的呈现,而只是想让数据用它做其他事情,那么最好的办法是传递数据(映射到选择字段) 连同表单一起添加到 twig 模板并直接使用。如果这不是一个选项,则可以像在表单主题中那样遍历选项,尽管您可能需要考虑首选选项。最简单的情况是

{% for choice in form.doctor_service_id.vars.choices %}
    {{ choice.label }}
    {{ choice.value }}
{% endfor %}
<select name="country"data-width="100%">
    {% for key,val in form.country.vars.choices %}
        <option value="{{ val.value }}" {{  form.country.vars.value == '' and key == 0 ? ' selected ' :(val.value == form.country.vars.value ? ' selected ' : '') }}>{{ val.label | trans }}</option>
    {% endfor %}
</select>