如何将CSS类添加到表单标签?


11

我想在使用Drupal 8 Form API的页面上的标签上添加CSS类。我一直无法在线找到有关如何应用的参考。我使用了以下解决方法,但是会产生一些奇怪的结果。

public function buildForm(array $form, FormStateInterface $form_state)
{
    $form['label1']  = array(
        '#type' => 'label',
        '#title' => $this->t('QUESTIONNAIRE'),
        '#id'         => 'lbl1',
        '#prefix'     => '<div class="caption1">',
        '#suffix'     => '</div>',
    ) ;

呈现的HTML是:

<div class="caption1"><label for="lbl1" class="control-label">
<div class="caption1"></div>QUESTIONNAIRE
  </label>

div语句不仅在错误的位置,而且呈现两次。

我发现几年前的帖子显示这是不可能的,但是我希望从那以后,对于D8,它已得到修复。我不想使用前缀/后缀,而是将其作为单独的数组元素。

PS:此站点是Drupal 8.0.0-rc2

Answers:


11

我知道这是一个旧主题,但对于任何使用Google的人来说。

线索就在这里template_preprocess_form_element()

$element += [
    '#title_display' => 'before',
    '#wrapper_attributes' => [],
    '#label_attributes' => [],
  ];

#label_attributes 是一个标准的属性数组,因此很容易设置一个类 ['class' => ['my-class', 'other-class']]

#title_display 取3个值:

  • before:将标签输出到元素之前。这是默认值。

  • after:在元素之后输出标签。例如,这用于radio和复选框#type元素。

  • 不可见:标签对于屏幕阅读器至关重要,标签使屏幕阅读器能够正确浏览表单,但视觉上会分散注意力。此属性为除屏幕阅读器以外的所有人隐藏标签。
  • attribute:在元素上设置title属性以创建工具提示,但不输出标签元素。仅复选框和收音机支持此功能

6

我刚刚检查了一下,但我不认为可以将类直接添加到label元素。

如您所知,通常在类中添加#attributes,如下所示:

 $form['foo'] = array(
  '#type' => 'textfield',
  '#title' => 'Foo',
  '#attributes' => array('class' => array('first-class', 'second-class')),
);

但是,我刚刚进行了测试,并且#attributes并未将类添加到Label元素。

您是否可以添加包装器表单元素,为其提供一个类,然后基于它是包装器元素的子元素来设置标签样式的方式?像这样:

$form['container'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('your-class')),
);
$form['container']['foo'] = array(
  '#type' => 'textfield',
  '#title' => 'Foo',
);

现在,这将在具有您的类的DIV元素内呈现示例文本字段(及其标签),即您可以设置标签样式:

.your-class label {
  /* your CSS here */
}

4

在Drupal> = 8.0.0中,有几个选项可以做到这一点。这些实际上都是围绕主题中的模板替代进行的,但是一个模块应该能够实现其他模块定义的模板预处理挂钩

  1. 最简单但非动态的选项是直接覆盖form-element-label.html.twig。如果所有标签都可以得到form-control该类,则可以使用此方法。
  2. 遵循这些原则,实现template_preprocess_form_element_label将允许您执行相同的操作并将form-control类添加到属性,而不会覆盖模板。
  3. 您还可以实现template_preprocess_form_element,并添加逻辑以不覆盖$variables['label'],而是从表单元素数组上某个已定义的键中获取其值。

2

对于提交按钮,我们可以添加如下所示的类:

$ form ['actions'] ['submit'] ['#attributes'] ['class'] [] ='use-ajax-submit';


1

我发现的最干净的选择是按照上面@mradcliffe的#3建议。例如,在您的表单定义中-

$form['distance'] = [
        '#type' => 'select',
        '#title' => 'Distance',
        '#required' => true,
        '#options' => [
            '10' => '10 Miles',
            '25' => '25 Miles',
            '50' => '50 Miles',
            '100' => '100 Miles'
        ],
        '#label_classes' => [
            'some-label-class'
        ]
    ];

然后在自定义模块中实现hook_preprocess_form_element:

/**
* Implementation of hook_preprocess_form_element
* @param $variables
*/
function your_module_preprocess_form_element(&$variables)
{
    if(isset($variables['element']['#label_classes'])) {
        $variables['label']['#attributes']['class'] = $variables['element']['#label_classes'];
    }
}

注意,这将覆盖Drupal要添加的所有标签类。就我而言,这很好。如果需要,可以更改上面的代码以防止出现这种情况。


1

要完成@Nate答案,如果要将这些类添加到现有表单中,可以在hook_form_alter中完成:

function your_module_form_alter(&$form, FormStateInterface &$form_state, $form_id)
{
    // for a textfield
    $form['distance']['widget'][0]['value']['#label_classes'] = ['some-label-class'];
    // for a radio field
    $form['country']['widget']['#label_classes'] = ['some-label-class'];
}

然后将hook_preprocess_form_element用于文本字段,或将hook_preprocess_fieldset用于单选字段:

/**
 * Implements hook_preprocess_hook().
 */
function your_module_preprocess_fieldset(&$variables)
{
  if(isset($variables['element']['#label_classes'])) {
    foreach ($variables['element']['#label_classes'] as $class) {
      $variables['legend']['attributes']->addClass($class);
    }
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.