在Symfony2中自定义选择/实体字段的呈现

时间:2013-03-28 14:42:07

标签: php symfony rendering customization

我希望在<select> s上使用其他数据呈现<option>元素。为了举例,我想要一个服务选择器(非多实体字段),在选择更改时重置另一个输入值。我对使用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属性(service是FormType中字段的名称)。 [请根据观察Symfony指定的当前字段的方式,将多个值连接起来。一个应该依赖于接口而不是逆向工程。] B)我不知道如何访问选择列表,即由entity字段{{1}组装的数组} 选项。 [由于我正在寻找一般解决方案,我不愿意将这些项目复制到控制器中的twig参数 - 只是为了避免这些建议。]
  2. 我会覆盖相关字段块的渲染,如在食谱的样式章节中所建议的那样,但是有三个问题。 A)我无法找出应该覆盖哪些块(因此我找不到样本)。 B)我会将参数从表单生成器传递到块,让它知道要呈现的额外query_builder属性,但我不知道如何执行此操作。最后 C)在我不需要偏离标准渲染的情况下(例如,当字段为多个时)我不知道如何回退到默认渲染。
  3. 所以这些实际上是5个问题(1A,1B,2A,2B,2C),但我认为它们对其他人一起回答更有用,因为它们都解决了我认为关于选择场渲染的无证问题。< / p>

2 个答案:

答案 0 :(得分:15)

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)您只能覆盖widgetlabelerrors块,documentation表示。您可以按窗口小部件名称(documentation)指定。像

这样的东西
{% 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 %}

答案 1 :(得分:1)

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

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

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