Come faccio ad aggiungere una classe CSS a un'etichetta del modulo?


11

Voglio aggiungere una classe CSS a un'etichetta su una pagina che utilizza l'API Form di Drupal 8. Non sono stato in grado di trovare un riferimento online su come applicarlo. Ho usato la seguente soluzione alternativa, ma produce alcuni risultati strani.

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

e il codice HTML reso è:

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

Non solo l'istruzione div si trova nel posto sbagliato, ma viene visualizzata due volte.

Avevo trovato post di diversi anni fa che dimostravano che ciò non era possibile, ma spero che da allora, e con D8, sia stato corretto. Non voglio farlo con prefisso / suffisso, ma come elemento di matrice separato.

PS: questo sito è Drupal 8.0.0-rc2

Risposte:


11

So che questo è un vecchio thread, ma per chiunque Googling.

L'indizio a questo è template_preprocess_form_element().

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

#label_attributes è un array di attributi standard, quindi è molto facile impostare una classe ['class' => ['my-class', 'other-class']]

#title_display accetta 3 valori:

  • prima: l'etichetta viene emessa prima dell'elemento. Questo è il valore predefinito.

  • after: l'etichetta viene emessa dopo l'elemento. Ad esempio, questo è usato per gli elementi radio e casella #type.

  • invisibile: le etichette sono fondamentali per gli screen reader per consentire loro di navigare correttamente tra i moduli ma possono distrarre visivamente. Questa proprietà nasconde l'etichetta per tutti tranne gli screen reader.
  • attributo: imposta l'attributo title sull'elemento per creare una descrizione comando ma non genera alcun elemento etichetta. Questo è supportato solo per caselle di controllo e radio

6

Ho appena controllato questo e non credo che sia possibile aggiungere una classe direttamente a un elemento etichetta.

Come probabilmente saprai, le classi vengono normalmente aggiunte con #attributes come segue:

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

Tuttavia, ho appena testato e #attributes non aggiunge classi a un elemento Label.

È possibile aggiungere un elemento del modulo wrapper, assegnargli una classe e quindi modellare l'etichetta in base al fatto che è figlio dell'elemento wrapper? Come questo:

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

Ora, questo renderà il campo di testo di esempio (e la sua etichetta) all'interno di un elemento DIV che ha la tua classe, cioè puoi modellare la tua etichetta:

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

4

Esistono diverse opzioni per farlo in Drupal> = 8.0.0. Tutto ruota intorno alle sostituzioni dei template in un tema, ma un modulo dovrebbe essere in grado di implementare hook di pre-elaborazione dei template definiti da altri moduli

  1. L'opzione più semplice, ma non dinamica, è quella di sovrascrivere direttamente form-element-label.html.twig . Questo potrebbe funzionare se tutte le etichette otterranno la form-controlclasse.
  2. Seguendo queste linee, l'implementazione di template_preprocess_form_element_label ti permetterebbe di fare la stessa cosa e aggiungere form-controlclasse agli attributi senza sovrascrivere il modello.
  3. È inoltre possibile implementare template_preprocess_form_element e aggiungere la logica per non sovrascrivere $variables['label'], ma prendere i suoi valori da una chiave definita sulla matrice dell'elemento del modulo.

2

Per i pulsanti di invio possiamo aggiungere una classe come di seguito:

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


1

L'opzione più pulita che ho trovato è secondo il suggerimento n. 3 di @ mradcliffe sopra. Ad esempio nella definizione del modulo -

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

Quindi in un modulo personalizzato implementare 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'];
    }
}

Nota che questo sostituirà tutte le classi di etichette che Drupal vuole aggiungere. Nel mio caso va bene. Il codice sopra può essere modificato per evitarlo, se necessario.


1

Per completare la risposta @Nate, se desideri aggiungere queste classi a un modulo esistente, puoi farlo in 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'];
}

E quindi usa hook_preprocess_form_element per il campo di testo o hook_preprocess_fieldset per il campo 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);
    }
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.