web-dev-qa-db-fra.com

Comment ajouter une classe CSS à une étiquette de formulaire?

Je veux ajouter une classe CSS à une étiquette sur une page qui utilise Drupal 8 Form API. Je n'ai pas pu trouver de référence en ligne sur la façon d'appliquer cela. J'ai utilisé ce qui suit solution de contournement, mais il produit des résultats étranges.

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>',
    ) ;

et le HTML rendu est:

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

Non seulement l'instruction div est au mauvais endroit, mais elle est rendue deux fois.

J'avais trouvé des publications il y a plusieurs années qui montrent que cela n'était pas possible, mais j'espère que depuis, et avec D8, il a été corrigé. Je ne veux pas le faire avec préfixe/suffixe, mais comme élément de tableau séparé.

PS: ce site est Drupal 8.0.0-rc2

11
Steve D.

Je sais que c'est un vieux fil, mais pour quiconque google.

L'indice est dans template_preprocess_form_element().

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

#label_attributes est un tableau d'attributs standard, il est donc très facile de définir une classe avec ['class' => ['my-class', 'other-class']]

#title_display prend 3 valeurs:

  • before: L'étiquette est sortie avant l'élément. C'est la valeur par défaut.

  • after: L'étiquette est sortie après l'élément. Par exemple, ceci est utilisé pour les éléments radio et case à cocher #type.

  • invisible: les étiquettes sont essentielles pour les lecteurs d'écran pour leur permettre de naviguer correctement dans les formulaires, mais peuvent être gênantes visuellement. Cette propriété masque l'étiquette pour tout le monde sauf les lecteurs d'écran.
  • attribut: définissez l'attribut title sur l'élément pour créer une info-bulle mais ne pas afficher d'élément label. Ceci est pris en charge uniquement pour les cases à cocher et les radios
11
mediaashley

Je viens de vérifier cela et je ne pense pas qu'il soit possible d'ajouter une classe directement à un élément label.

Comme vous le savez probablement, les classes sont normalement ajoutées avec #attributes comme suit:

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

Cependant, je viens de tester et #attributes n'ajoute pas de classes à un élément Label.

Est-il possible pour vous d'ajouter un élément de formulaire wrapper, de lui donner une classe puis de styliser votre étiquette en fonction du fait qu'il s'agit d'un enfant de l'élément wrapper? Comme ça:

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

Maintenant, cela rendra l'exemple de champ de texte (et son étiquette) à l'intérieur d'un élément DIV qui a votre classe, c'est-à-dire que vous pouvez styliser votre étiquette:

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

Il existe plusieurs options pour le faire dans Drupal> = 8.0.0. Tout cela tourne vraiment autour des remplacements de modèle dans un thème, mais un module devrait être capable de implémenter les crochets de prétraitement de modèle défini par d'autres modules

  1. L'option la plus simple mais non dynamique consiste à remplacer directement form-element-label.html.twig . Cela pourrait fonctionner si toutes les étiquettes obtiennent le form-control classe.
  2. En suivant ces lignes, implémenter template_preprocess_form_element_label vous permettrait de faire la même chose et d'ajouter form-control classe aux attributs sans redéfinir le modèle.
  3. Vous pouvez également implémenter template_preprocess_form_element , et ajouter une logique pour ne pas écraser $variables['label'], mais prenez ses valeurs dans une clé définie du tableau des éléments du formulaire.
4
mradcliffe

Pour les boutons de soumission, nous pouvons ajouter une classe comme ci-dessous:

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

2
Subhash

Pour compléter la réponse @Nate, si vous souhaitez ajouter ces classes à un formulaire existant, vous pouvez le faire dans 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'];
}

Et puis utilisez le hook_preprocess_form_element pour le champ de texte ou un hook_preprocess_fieldset pour le champ radio:

/**
 * 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

L'option la plus propre que j'ai trouvée est conforme à la suggestion # 3 de @ mradcliffe ci-dessus. Par exemple, dans votre définition de formulaire -

$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'
        ]
    ];

Ensuite, dans un module personnalisé, implémentez 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'];
    }
}

Notez que cela remplacera toutes les classes d'étiquettes Drupal veut ajouter. Dans mon cas, c'est très bien. Le code ci-dessus peut être modifié pour éviter cela si nécessaire.

1
Nate