¿Cómo puedo agregar una clase a una etiqueta?

8

Necesito agregar un nombre de clase a ciertas etiquetas creadas por la API de formulario de Drupal como esta:

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

Si uso lo siguiente, <textarea>obtiene una clase, pero no la etiqueta.

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

Estoy buscando algo similar que agregará una clase al <label>.

Shawn
fuente
También debe considerar si aún no puede orientar esa etiqueta de campo con CSS utilizando la clase de contenedor principal para el nombre del campo, por ejemplo.field-name-field-myfield label{ color:red; }
David Thomas

Respuestas:

6

No puede establecer una clase en la etiqueta del elemento del formulario utilizando las propiedades de la API del formulario. Sin embargo, puede establecer un prefijo y un sufijo para envolver el elemento (etiqueta + área de texto) y usar un selector CSS anidado para lograr lo que está tratando de hacer.

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

y en el CSS, puede seleccionar la etiqueta como esta:

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

No es una solución decente, pero así es como suelo hacer esto, y he visto a otros hacer. #attributeses para el elemento de entrada en sí mismo, por lo que es correcto, su código agrega la myClassclase al textarea.

AyeshK
fuente
7

Esta publicación en StackOverflow dice que la API de formularios de Drupal no admite agregar clases a las etiquetas, pero contiene una solución decente:

En su lugar, puede orientarlo utilizando la clase de contenedor para el campo y la etiqueta:

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

La documentación de la API para theme_form_element_label () muestra por qué las etiquetas no son posibles (al menos no listas para usar ): la matriz de atributos se inicializa en la función de tema y se completa con solo dos clases opcionales ('opción' y 'elemento -invisible').

Entonces, ¿es completamente imposible? De hecho, creo que se puede hacer, pero debo agregar que no lo he intentado yo mismo. Podrías intentar:

  • Agregue una nueva #label_attributespropiedad a algunos (o todos) elementos de formulario usando hook_element_info_alter () en un módulo personalizado;
  • Reemplace theme_form_element_label () y haga que combine la $attributesmatriz con el valor de $element['#label_attributes'].

Si vas a probar esto, avísanos si funcionó.

marcvangend
fuente
Debido a limitaciones de tiempo, buscaré la solución más fácil propuesta por Ayesh K. Sin embargo, parece una buena solución, puede ayudar a alguien más. +1
Shawn
Más 1 por mencionar la función de tema theme_form_element_label ()
Ideograma
Soluciones alternativas: si se requiere JS en el sitio, es probable que ajustar el DOM sea más fácil. Si no, otra forma (media) sería eliminar '#title'o configurar '#title_display' => 'invisible'y luego simplemente hacer '#suffix' => '<label for="TheElementId" class="option">Display This Text</label>'. Eso hace que aparezca fuera del contenedor que <div>Drupal usa para sus elementos de entrada de formulario, pero una regla CSS podría hacer que no se vea diferente.
SeldomNeedy
2

Ampliando la respuesta de Ayesh, he incluido un caso de uso de ejemplo para dicho código. Si bien la respuesta de marvangend es mucho más drupalesca, se está cavando mucho para obtener un resultado muy simple. Mantener elementos específicos de formulario y CSS incluidos con dicho formulario es el caso de uso general, lo que nos permite apuntar y actuar sobre elementos internos es un poco más específico.

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
fuente
2

En Drupal 8, hazlo simplemente agregando el archivo 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']
    );
  }
}

y agregue los #label_attributes en la creación del formulario:

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

Encontré una forma relativamente fácil de lograr esto usando el módulo Fences D7. Este módulo viene con muchos archivos de plantilla para personalizar los campos. Edite el campo al que le gustaría dar una clase única y cambie el marcado de envoltura a algo relevante para usted. Después de eso, busque el archivo de plantilla correspondiente dentro del módulo y cópielo en sus sitios / all / themes / THEME_NAME.

antes de

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

Después

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

Al agregarlo <?php print $label; ?>, imprime el nombre del campo como una clase, lo que le permite apuntar a todas las etiquetas de campo individualmente. ¡Espero que esto ayude a alguien más!

sen2008
fuente
0

Está sucio, pero puede agregar HTML a la propiedad '# title':

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

Me sorprende que funcione. Creo que Drupal filtraría esto, pero no. Entonces, puedes envolver la etiqueta con otra clase:

<label for="edit-m-vernacularname" class="inline"><span title="HELP!">Common name
</span> </label>
Ideograma
fuente