10

我希望一个<select>元素在其<option>s 上使用附加数据进行渲染。例如,我想要一个服务选择器(非多个实体字段),在选择更改时重置另一个输入值。我对使用 JS 数据结构不感兴趣,我需要渲染的字段如下所示:

<select name="...">
    <option value="1" data-price="90">Service 1</option>
    <option value="2" data-price="40">Service 2</option>
</select>

我会采用两种不同的解决方案,并且很高兴看到它们的答案。

  1. form通过使用传递给树枝的变量开始组装上述 HTML 代码,我将在 Twig 中手动呈现该字段。我有两个问题解决这个问题。A)我找不到一种安全的方法来告诉文件应该命名什么,即如何name通过使用变量获得 Symfony 期望的属性form.service(服务是 FormType 中字段的名称)。[请原谅我根据Symfony当前如何命名字段来连接一些值的技巧;应该依赖接口而不是逆向工程。] B)我不知道如何访问选项列表,即由entity字段组装的数组query_builder选项。[因为我正在寻找一个通用的解决方案,我不愿意将这些项目复制到控制器中的一个 twig-parameter ——只是为了避免这样的建议。]
  2. 正如食谱的表单样式章节中所建议的那样,我会覆盖相关字段块的呈现,但这存在三个问题。A)我找不到应该覆盖哪些块(所以我找不到样本)。B)我会将参数从表单构建器传递给块,让它知道data-要呈现哪些额外属性,但我不知道该怎么做。最后是C)在那些我不需要偏离标准渲染的情况下(例如,当字段是多个时)我不知道如何回退到默认渲染。

所以这些实际上是 5 个问题(1A、1B、2A、2B、2C),但我认为它们对一起回答的其他人更有用,因为它们都解决了我认为关于选择字段渲染的未记录点。

4

2 回答 2

18

1.手动渲染。最好是单独的字段表单,而不是在某个地方重复,因为它需要更少的时间来工作。

A)获取您可以使用的字段名称form.service.vars.full_name

B)选择列表 - form.service.vars.choices。它是一个数组ChoiceView,要让实体简单地访问公共data财产。

{% for choice in form.service.vars.choices %}
    {% set service_entity = choice.data %}
{% endfor %}

2.通过覆盖模板。如果您喜欢蛮力选择必须覆盖的块的名称。

A)您只能按照文档所述覆盖widget,labelerrors块。您可以按小部件名称(文档)指定块。就像是

{% block _form_service_widget %}
    {% if expanded %}
        {{ block('choice_widget_expanded') }}
    {% else %}
        {{ block('my_service_widget') }}
    {% endif %}
{% endblock %}

{% block my_service_widget %}
{% spaceless %}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
        {% if empty_value is not none %}
            <option value="">{{ empty_value|trans({}, translation_domain) }}</option>
        {% endif %}
        {% set options = choices %}
        {{ block('my_service_options') }}
    </select>
{% endspaceless %}
{% endblock my_service_widget %}

{% block my_service_options %}
{% spaceless %}
    {% for group_label, choice in options %}
        {# here you can access choice #}
        <option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.label|trans({}, translation_domain) }}</option>
    {% endfor %}
{% endspaceless %}
{% endblock my_service_options %}
于 2013-07-25T04:17:31.753 回答
3

您可以使用choice_attr表单构建器中的选项:

$builder->add('myField', ChoiceType:class, [
        ....
        'choice_attr' => function($val, $key, $index) {
            return ['data' => '...', 'class' => '', ... etc ];
        },
        ....
]);

这会将属性应用于您选择的每个option, checkbox, radio(取决于您expandedmultiple选项的选择)

于 2017-02-22T06:35:56.123 回答