Wie füge ich einer Formularbezeichnung eine CSS-Klasse hinzu?

11

Ich möchte einer Beschriftung auf einer Seite, die die Drupal 8 Form API verwendet, eine CSS-Klasse hinzufügen. Ich konnte online keine Referenz finden, wie ich das anwenden kann. Ich habe die folgende Problemumgehung verwendet, aber sie führt zu einigen seltsamen Ergebnissen.

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

und der gerenderte HTML ist:

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

Die div-Anweisung befindet sich nicht nur an der falschen Stelle, sondern wird auch zweimal gerendert.

Ich hatte vor einigen Jahren Postings gefunden, die zeigen, dass dies nicht möglich war, aber ich hoffe, dass es seitdem und mit D8 behoben wurde. Ich möchte es nicht mit Präfix / Suffix machen, sondern als separates Array-Element.

PS: Diese Seite ist Drupal 8.0.0-rc2

Steve D.
quelle

Antworten:

11

Ich weiß, dass dies ein alter Thread ist, aber für jeden, der googelt.

Der Hinweis darauf ist in template_preprocess_form_element().

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

#label_attributes ist ein Standardattributarray, mit dem eine Klasse sehr einfach festgelegt werden kann ['class' => ['my-class', 'other-class']]

#title_display nimmt 3 Werte an:

  • vor: Die Beschriftung wird vor dem Element ausgegeben. Dies ist die Standardeinstellung.

  • after: Das Label wird nach dem Element ausgegeben. Dies wird beispielsweise für Radio- und Checkbox-Elemente vom Typ # verwendet.

  • unsichtbar: Beschriftungen sind für Bildschirmleser von entscheidender Bedeutung, damit sie ordnungsgemäß durch Formulare navigieren können, aber visuell ablenken können. Diese Eigenschaft verbirgt die Beschriftung für alle außer Bildschirmleseprogrammen.
  • Attribut: Legen Sie das title-Attribut für das Element fest, um eine QuickInfo zu erstellen, geben Sie jedoch kein Beschriftungselement aus. Dies wird nur für Kontrollkästchen und Radios unterstützt
Mediaashley
quelle
6

Ich habe dies gerade überprüft und glaube nicht, dass es möglich ist, eine Klasse direkt zu einem Beschriftungselement hinzuzufügen.

Wie Sie höchstwahrscheinlich wissen, werden Klassen normalerweise mit #attributes wie folgt hinzugefügt:

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

Ich habe es jedoch gerade getestet und #attributes fügt einem Label-Element keine Klassen hinzu.

Ist es Ihnen möglich, ein Wrapper-Formularelement hinzuzufügen, ihm eine Klasse zuzuweisen und dann Ihre Beschriftung basierend auf der Tatsache zu formatieren, dass es ein untergeordnetes Element des Wrapper-Elements ist? So was:

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

Dadurch wird das Beispieltextfeld (und seine Beschriftung) in einem DIV-Element gerendert, das Ihre Klasse enthält, dh Sie können Ihre Beschriftung formatieren:

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

In Drupal> = 8.0.0 gibt es dafür mehrere Möglichkeiten. Diese alle drehen sich wirklich um Vorlagenüberschreibungen in einem Thema, aber ein Modul sollte in der Lage sein, Vorlagenvorverarbeitungs-Hooks zu implementieren, die von anderen Modulen definiert wurden

  1. Die einfachste, aber nicht dynamische Option besteht darin, form-element-label.html.twig direkt zu überschreiben . Dies könnte funktionieren, wenn alle Labels die form-controlKlasse erhalten.
  2. Wenn Sie in diesem Sinne folgen, können Sie mit der Implementierung von template_preprocess_form_element_label dasselbe tun und form-controlAttributen eine Klasse hinzufügen , ohne die Vorlage zu überschreiben.
  3. Sie können auch template_preprocess_form_element implementieren und Logik hinzufügen, um nicht zu überschreiben $variables['label'], sondern die Werte von einem definierten Schlüssel im Formularelementarray zu übernehmen.
mradcliffe
quelle
2

Für Submit-Buttons können wir die folgende Klasse hinzufügen:

$ form ['Aktionen'] ['Submit'] ['# Attribute'] ['Klasse'] [] = 'use-ajax-submit';

Subhash
quelle
1

Die sauberste Option, die ich gefunden habe, entspricht dem obigen Vorschlag Nr. 3 von @ mradcliffe. ZB in Ihrer Formulardefinition -

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

Implementieren Sie dann in einem benutzerdefinierten Modul 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'];
    }
}

Beachten Sie, dass dadurch alle Beschriftungsklassen überschrieben werden, die Drupal hinzufügen möchte. In meinem Fall ist das in Ordnung. Der obige Code kann geändert werden, um dies bei Bedarf zu verhindern.

Nate
quelle
1

Um die @ Nate-Antwort zu vervollständigen, können Sie diese Klassen in einem vorhandenen Formular hinzufügen, indem Sie diese Klassen in hook_form_alter hinzufügen:

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

Verwenden Sie dann das hook_preprocess_form_element für das Textfeld oder ein hook_preprocess_fieldset für das Funkfeld:

/**
 * 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);
    }
  }
}
Marie P.
quelle