web-dev-qa-db-ja.com

CSSクラスをフォームラベルに追加するにはどうすればよいですか?

Drupal 8フォーム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ステートメントが間違った場所にあるだけでなく、2回レンダリングされます。

私は数年前にこれが不可能であることを示す投稿を見つけましたが、それ以降、D8で修正されたことを期待しています。接頭辞/接尾辞ではなく、個別の配列要素として実行したいと思います。

PS:このサイトはDrupal 8.0.0-rc2です。

11
Steve D.

私はこれが古いスレッドであることを知っていますが、誰にとってもグーグルです。

この手がかりはtemplate_preprocess_form_element()にあります。

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

#label_attributesは標準の属性配列なので、['class' => ['my-class', 'other-class']]でクラスを設定するのは非常に簡単です

#title_displayは3つの値を取ります:

  • before:ラベルは要素の前に出力されます。これがデフォルトです。

  • after:要素の後にラベルが出力されます。たとえば、これはラジオおよびチェックボックスの#type要素に使用されます。

  • 非表示:ラベルは、スクリーンリーダーがフォームを適切に移動できるようにするために重要ですが、視覚的に煩わしい場合があります。このプロパティは、スクリーンリーダー以外のすべてのユーザーに対してラベルを非表示にします。
  • 属性:要素にタイトル属性を設定して、ツールチップを作成しますが、ラベル要素は出力しません。これはチェックボックスとラジオでのみサポートされています
11
mediaashley

これをチェックしたところ、ラベル要素に直接クラスを追加することができないと思います。

ご存知のように、クラスは通常、次のように#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',
);

これで、例のテキストフィールド(およびそのラベル)が、your-classを含むDIV要素内にレンダリングされます。つまり、ラベルをスタイルできます。

.your-class label {
  /* your CSS here */
}
6
Markus Sipilä

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']を上書きしないようにロジックを追加して、フォーム要素配列の定義済みキーから値を取得することもできます。
4
mradcliffe

送信ボタンについては、以下のようなクラスを追加できます。

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

2
Subhash

@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);
    }
  }
}
1
Marie P

私が見つけた最もクリーンなオプションは、上記の@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