【问题标题】:Symfony2 - How to put label and input for checkboxes/radios in a same line?Symfony2 - 如何将复选框/收音机的标签和输入放在同一行?
【发布时间】:2012-07-15 11:20:15
【问题描述】:

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

  • 第一个收音机小部件
  • 第一个标签
  • 第二个收音机小部件
  • 标签

这里是 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 %}

【问题讨论】:

  • 你不能只使用 CSS 来设置样式吗?
  • 感谢您的回复,但您能告诉我怎么做吗?我是计算机科学的初学者。

标签: php symfony twig


【解决方案1】:

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

{% 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 %}

【讨论】:

  • 不知道为什么这被否决了,因为它产生了 2.0.x 上请求的输出
  • 不适用于 Symfony 2.3,因为choice_widget 已被拆分为choice_widget_expanded 和choice_widget_collapsed。如果您逐字遵循此建议,如果会影响 select 的行为。请参阅下面的更新解决方案。
  • 如何使用此解决方案应用label_attr?例如。如果我想通过form_widget向标签添加一个类。
  • 嗨@mwld。我已经有一段时间没有积极与 Symfony 合作了,所以我不知道如何回答你的问题。我建议将其作为一个新问题发布,因为此评论不太可能获得很多意见。祝你好运。
【解决方案2】:

在 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 %}

【讨论】:

  • 如果您想在标签中启用 HTML,请将 label|trans 更改为 label|trans|raw
【解决方案3】:

注意:更新了 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 %}

覆盖单选按钮

{% 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 %}

【讨论】:

  • 将这些块放在一个单独的文件中,然后在字段上使用 form_widget 之前,您可以执行 {% form_theme form.field '::theme.html.twig' %} 来使用它。我花了一段时间才弄清楚如何将这些实际用于一个领域:)
【解决方案4】:

当一个标签被渲染时,它将包含一个 for 属性 - 这会将 label 链接到 input - see the docs on label here 将输出更改为您建议的内容只是链接 label 和的另一种方式input

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

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

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

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

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

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

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

Working example here

【讨论】:

  • 好的,谢谢它适用于您的 css,但我想使用类似的东西 {{ form_widget(form.field1, {'attr' : {'class': 'some_css'} }) } } with .some_css { display: inline-block;宽度:200px; }​ 并且它不会那样工作
  • @reveclaire form_widget 是输入。你需要form_label
【解决方案5】:

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

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

input, label {
 display: inline;
}

【讨论】:

  • HTML 是完全有效的——将input 放在label 中很好——它只是将labelinput 相关联——就像for 属性一样——@ 987654321@
  • @MrGlass - 我正要提出与我刚刚所做的相同的解决方案 - 只是为了发现你比我早了近 5 年!大声笑
【解决方案6】:

在 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 来猜测这些内容

希望这会有所帮助。

【讨论】:

    【解决方案7】:

    在 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 %}
    

    【讨论】:

      【解决方案8】:

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

      在你的树枝上又快又脏:

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

      如果 Symfony 有一个更简单的解决方案,我会很高兴的。

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

      【讨论】:

        【解决方案9】:

        您可以像这样覆盖 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 %}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-26
          • 2021-09-27
          • 2017-01-09
          • 2019-03-09
          相关资源
          最近更新 更多