Symfony2 - 如何将复选框/无线电的标签和输入放在同一行?

时间:2012-07-16 15:13:17

标签: php symfony twig

在我的表格中,我有一些复选框, 但默认情况下,我有

  • 第一个广播小部件
  • 第一个标签
  • 第二个广播小部件
  • 标签

以下是SYmfony2生成的html代码:

  <div>
    <input ...>
    <label ...></label>
    <input ...>
    <label ...></label>
  </div>

我想要具有:

第一个无线电小部件第一个标签
第二个无线电小部件第二个标签

html代码为:

  <label .....><input ....></label>

我想我必须覆盖choice_widget,但不知道如何将输入和标签放在同一行上

这是我可能需要覆盖的choice_widget:

    {% block choice_widget %}
        {% spaceless %}
            {% if expanded %}
                <div {{ block('widget_container_attributes') }}>
                   {% for child in form %}
                      {{ form_widget(child) }}  {{ form_label(child) }}
                   {% endfor %}
                </div>
            {% else %}
                <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
                {% if empty_value is not none %}
                     <option value="">{{ empty_value|trans }}</option>
                {% endif %}
                {% if preferred_choices|length > 0 %}
                    {% set options = preferred_choices %}
                    {{ block('widget_choice_options') }}
                        {% if choices|length > 0 and separator is not none %}
                            <option disabled="disabled">{{ separator }}</option>
                       {% endif %}
                {% endif %}
                {% set options = choices %}
                {{ block('widget_choice_options') }}
                </select>
           {% endif %}
      {% endspaceless %}
   {% endblock choice_widget %}

9 个答案:

答案 0 :(得分:30)

我遇到了同样的问题,我无法找到解决方案,所以我自己解决了问题。你确实需要覆盖{% block choice_widget %}块是正确的。第一步是从{{ form_label(child) }}部分删除打印出单独标签的{% if expanded %}行。

{% block choice_widget %}
{% spaceless %}
    {% if expanded %}
        <div {{ block('widget_container_attributes') }}>
        {% for child in form %}
            {{ form_widget(child) }}
        {#  {{ form_label(child) }} <--------------------- remove this line #}  
        {% endfor %}
        </div>
    {% else %}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
        {% if empty_value is not none %}
            <option value="">{{ empty_value|trans }}</option>
        {% endif %}
        {% if preferred_choices|length > 0 %}
            {% set options = preferred_choices %}
            {{ block('widget_choice_options') }}
            {% if choices|length > 0 and separator is not none %}
                <option disabled="disabled">{{ separator }}</option>
            {% endif %}
        {% endif %}
        {% set options = choices %}
        {{ block('widget_choice_options') }}
    </select>
    {% endif %}
{% endspaceless %}
{% endblock choice_widget %}

现在您只需处理{% block checkbox_widget %}块中的标签打印。

{% block checkbox_widget %}
{% spaceless %}
    <label  for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}

您需要对{% block radio_widget %}执行相同的操作,因为它现在不会有标签。

{% block radio_widget %}
{% spaceless %}
    <label  for="{{ id }}"><input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock radio_widget %}

答案 1 :(得分:13)

在Alberto Gaona和James的帮助下,Symfony 2.4正确的解决方案集成了BS3收音机和复选框如下:

在您看来,您有:

{% form_theme form 'AcmeDemoBundle:Form:fields.html.twig' %}

// A radio or checkbox input
{{ form_widget(form.example) }}

然后在您的fields.html.twig中(覆盖https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig;请参阅http://symfony.com/doc/current/cookbook/form/form_customization.html

{# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #}

{% block choice_widget_expanded %}
{% spaceless %}
    <div {{ block('widget_container_attributes') }}>
    {% for child in form %}
        {% if multiple %}
            <div class="checkbox">
        {% else %}
            <div class="radio">
        {% endif %}

        {{ form_widget(child) }}
        </div>
    {% endfor %}
    </div>
{% endspaceless %}
{% endblock choice_widget_expanded %}

{% block checkbox_widget %}
{% spaceless %}
{% if label is empty %}
    {% set label = name|humanize %}
{% endif %}
    <label  for="{{ id }}">
        <input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans({}, translation_domain) }}
    </label>
{% endspaceless %}
{% endblock checkbox_widget %}

{% block radio_widget %}
{% spaceless %}
{% if label is empty %}
    {% set label = name|humanize %}
{% endif %}
    <label  for="{{ id }}">
        <input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans({}, translation_domain) }}
    </label>
{% endspaceless %}
{% endblock radio_widget %}

答案 2 :(得分:11)

注意:更新了Symfony 2.3的Bob F解决方案(参见https://github.com/symfony/symfony/blob/2.3/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig):

覆盖choice_widget_expanded:

{% block choice_widget_expanded %}
{% spaceless %}
    <div {{ block('widget_container_attributes') }}>
    {% for child in form %}
        {{ form_widget(child) }}
    {% endfor %}
    </div>
{% endspaceless %}
{% endblock choice_widget_expanded %}

覆盖复选框(引导程序样式):

{% block checkbox_widget %}
{% spaceless %}
    <label  for="{{ id }}" class="checkbox {% if checked %}checked{% endif %}" ><span class="icons"><span class="first-icon fui-checkbox-unchecked"></span><span class="second-icon fui-checkbox-checked"></span></span><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}

覆盖radiobutton

{% block radio_widget %}
{% spaceless %}
    <label  for="{{ id }}"><input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock radio_widget %}

答案 3 :(得分:2)

呈现标签时,它会包含for属性 - 这会将label链接到input - see the docs on label here,将输出更改为您建议的另一个链接labelinput

的方式

如果您希望标签显示在输入的左侧,则需要将模板更改为:

{% for child in form %}
   <div>
      {{ form_label(child) }}  {{ form_widget(child) }} 
   </div>
{% endfor %}

label之前呈现input然后会创建以下输出

<div>
  <div>
    <label ...></label>
    <input ...>
  </div>
  <div>
    <label ...></label>
    <input ...>
  </div>
</div>

然后,您可以应用一些CSS样式以使其显示为内联:

​div label {
    display: inline-block;
    width: 200px;
}​

默认情况下 - 如果没有任何CSS,label会在input之前与此HTML布局对齐 - 但inline-block也允许您使用width属性确保所有字段都正确排列 - 无论标签文本的长度如何

Working example here

答案 4 :(得分:1)

将表单输入放在label标签内会导致HTML损坏。

你的目标是什么?如果您只是想在浏览器中将标签和输入显示在同一行,那么您可以使用css:

input, label {
 display: inline;
}

答案 5 :(得分:0)

在Symfony 2.4中,这并不像预期的那样有效。

{% block checkbox_widget %}
{% spaceless %}
  <label  for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}

......标签不可用。您需要添加以下内容:

{% if label is empty %}
  {% set label = name|humanize %}
{% endif %}

完整的解决方案是:

{% block checkbox_widget %}
{% if label is empty %}
  {% set label = name|humanize %}
{% endif %}
{% spaceless %}
  <label  for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}

答案 6 :(得分:0)

标签非常简单,所以我个人更喜欢手动渲染它。

你的枝条快速而肮脏:

<label for="field">
    {{ form_widget(form.field) }} Field Label
</label>

如果Symfony有一个更简单的解决方案,无论如何,我都会喜欢。

当然上面的答案可能更优雅,但不是。 ;)

答案 7 :(得分:0)

在Symfony 3+中,您可以简单地通过label_attr将radio-inline类传递给表单:

$builder->add('type', ChoiceType::class, [
    'expanded' => true, 
    'label_attr' => ['class' => 'radio-inline']
]);

不需要创建自定义窗口小部件...

您可以通过在供应商目录(src / Symfony / Bridge / Twig / Resources / views / Form / bootstrap_4_layout.html.twig)中查看Symfony提供的bootstrap_4_layout.html.twig来猜测那些事情。

希望这会有所帮助。

答案 8 :(得分:-1)

你可以像这样覆盖form_row函数(修改为适合twitter bootstrap的temple标签/复选框): (在那个例子中它是“复选框”但我认为“无线电”它的工作方式相同)

{% extends 'form_div_layout.html.twig' %}

{% block field_row %}
{% spaceless %}
    {% if 'checkbox' in types %}
        {% if not compound %}
            {% set label_attr = label_attr|merge({'for': id}) %}
        {% endif %}
        {% if required %}
            {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
        {% endif %}
        {% if label is empty %}
            {% set label = name|humanize %}
        {% endif %}
        <label class="checkbox" {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}
           {{ block('checkbox_widget') }}
        </label>
    {% else %}
        {{ parent() }}
    {% endif %}
{% endspaceless %}
{% endblock field_row %}