Comment puis-je ajouter une classe à une étiquette?

8

J'ai besoin d'ajouter un nom de classe à certaines étiquettes créées par l'API de formulaire de Drupal comme ceci:

$form['name'] => array(
  '#type' => 'textfield',
  '#title' => 'Prénom'
);

Si j'utilise ce qui suit, le <textarea>obtient une classe, mais pas l'étiquette.

$form['name']['#attributes']['class'] = array('myClass');

Je cherche quelque chose de similaire qui ajoutera une classe au <label>.

Shawn
la source
Vous devriez également considérer si vous ne pouvez pas déjà cibler cette étiquette de champ avec CSS en utilisant la classe de conteneur parent pour le nom du champ, par exemple.field-name-field-myfield label{ color:red; }
David Thomas

Réponses:

6

Vous ne pouvez pas définir une classe sur la balise label de l'élément de formulaire à l'aide des propriétés de l'API Form. Cependant, vous pouvez définir un préfixe et un suffixe pour envelopper l'élément (étiquette + zone de texte) et utiliser un sélecteur CSS imbriqué pour accomplir ce que vous essayez de faire.

$form['name'] => array(
  '#type' => 'textfield',
  '#title' => 'Prénom'
  '#prefix' => '<div class="myClass">',
  '#suffix' => '</div>'
);

et dans le CSS, vous pouvez sélectionner la balise label comme ceci:

.myClass label {
  text-transform: uppercase; /* just for example */
}

Ce n'est pas une solution décente, mais c'est comme ça que je fais d'habitude et j'en ai vu d'autres. #attributesest pour l'élément d'entrée lui-même, il est donc correct que votre code ajoute la myClassclasse à la textarea.

AyeshK
la source
7

Ce post sur StackOverflow dit que l'API Drupal Form ne prend pas en charge l'ajout de classes aux étiquettes, mais il contient une solution de contournement décente:

Au lieu de cela, vous pouvez le cibler à l'aide de la classe wrapper pour le champ et l'étiquette:

.form-item-field-foo label {
  /* CSS here */
}

La documentation de l'API pour theme_form_element_label () montre pourquoi les étiquettes ne sont pas possibles (du moins pas prêtes à l' emploi ): le tableau d'attributs est initialisé dans la fonction de thème et rempli avec seulement deux classes facultatives ('option' et 'element -invisible').

Alors, est-ce complètement impossible? En fait, je pense que c'est possible, mais je dois ajouter que je n'ai pas essayé moi-même. Vous pouvez essayer de:

  • Ajoutez une nouvelle #label_attributespropriété à certains (ou à tous) les éléments de formulaire à l'aide de hook_element_info_alter () dans un module personnalisé;
  • Remplacez theme_form_element_label () et faites-le fusionner le $attributestableau avec la valeur de $element['#label_attributes'].

Si vous voulez essayer, veuillez nous faire savoir si cela a fonctionné.

marcvangend
la source
En raison de contraintes de temps, je vais opter pour la solution plus simple proposée par Ayesh K. Cela semble cependant être une bonne solution, cela peut aider quelqu'un d'autre. +1
Shawn
Plus 1 pour avoir mentionné la fonction de thème theme_form_element_label ()
Idéogramme
Solutions de contournement: si nécessiter JS sur le site est acceptable, peaufiner le DOM est probablement le plus simple. Sinon, une autre façon (moyenne) serait de supprimer '#title'ou de définir '#title_display' => 'invisible', puis de le faire '#suffix' => '<label for="TheElementId" class="option">Display This Text</label>'. Cela le fait apparaître en dehors de l'encapsulage <div>utilisé par Drupal pour ses éléments d'entrée de formulaire, mais une règle CSS pourrait ne pas faire la différence.
SeldomNeedy
2

En développant la réponse d'Ayesh, j'ai inclus un exemple d'utilisation pour un tel code. Bien que la réponse de marvangend soit beaucoup plus Drupalesk, il faut beaucoup creuser pour un résultat très simple. Garder les éléments spécifiques au formulaire et CSS regroupés avec ledit formulaire est le cas d'utilisation général, nous permettant de cibler et d'agir sur les éléments internes est un tout petit peu plus spécifique.

http://legomenon.io/article/drupal-7-adding-form-placeholder-attributes

function mymodule_form_alter(&$form, $form_state, $form_id) {
  switch ($form_id) {
    // Waterfall.
    case 'webform_client_form_16':
    case 'webform_client_form_51':
    case 'webform_client_form_64':
    case 'webform_client_form_78':
      $exclude = array('select', 'radios', 'checkboxes', 'managed_file');
      foreach ($form['submitted'] as $name => $component) {
        if (!in_array($component['#type'], $exclude) && $name != '#tree') {
          $form['submitted'][$name]['#prefix'] = '<span class= "label-invisible">';
          $form['submitted'][$name]['#suffix'] = '</span>';
          $form['submitted'][$name]['#attributes']['placeholder'] = $component['#title'];
        }
      }
      $form['#attached']['css'] = array(
        drupal_get_path('module', 'mymodule') . '/css/mymodule.form.css',
      );
    break;
  }
}
Nicolas
la source
2

Sur Drupal 8, faites-le simplement en ajoutant votre fichier your_module.module

function your_module_preprocess_form_element(&$variables) {

  $element = $variables['element'];
  if (isset($element['#label_attributes'])) {
    $variables['label']['#attributes'] = array_merge(
      $variables['attributes'],
      $element['#label_attributes']
    );
  }
}

et ajoutez les #label_attributes lors de la création du formulaire:

$form['some_field'] = [
  [...]
  '#label_attributes' => [
    'some_attr' => 'some_value',
  ]
]
vibby
la source
0

J'ai trouvé un moyen relativement facile d'accomplir cela en utilisant le module Fences D7. Ce module est livré avec de nombreux fichiers de modèles pour personnaliser les champs. Modifiez le champ auquel vous souhaitez attribuer une classe unique et modifiez le balisage de wrapper en quelque chose de pertinent pour vous. Après cela, recherchez le fichier de modèle correspondant dans le module et copiez-le dans vos sites / tous / thèmes / THEME_NAME.

Avant

<span class="field-label"<?php print $title_attributes; ?>>
  <?php print $label; ?>:
</span>

Après

<span class="<?php print $label; ?> field-label"<?php print $title_attributes; ?>>
  <?php print $label; ?>:
</span>

En l'ajoutant <?php print $label; ?>, il imprime le nom du champ en tant que classe, vous permettant de cibler toutes les étiquettes de champ individuellement. J'espère que ça aidera quelqu'un d'autre!

sen2008
la source
0

C'est sale, mais vous pouvez ajouter du HTML à la propriété '# title':

$form['some_element'] = array(
  '#type'          => 'textfield',
  '#title'         => '<span title="HELP!">'.t($subchildlabel).'</span>',
  '#default_value' => 
) 
 
);

Je suis moi-même surpris que cela fonctionne. Je pense que Drupal filtrerait cela, mais non. Vous pouvez donc envelopper l'étiquette avec une autre classe:

<label for="edit-m-vernacularname" class="inline"><span title="HELP!">Common name
</span> </label>
Idéogramme
la source