Jak mogę dodać klasę do etykiety?

8

Muszę dodać nazwę klasy do niektórych etykiet utworzonych przez interfejs API formularza Drupala w następujący sposób:

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

Jeśli użyję następujących, <textarea>klasa otrzyma klasę, ale nie etykietę.

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

Szukam czegoś podobnego, co doda klasę do <label>.

Shawn
źródło
Należy również rozważyć, czy nie można już kierować do tej etykiety pola za pomocą CSS przy użyciu nadrzędnej klasy kontenera dla nazwy pola, np..field-name-field-myfield label{ color:red; }
David Thomas

Odpowiedzi:

6

Nie można ustawić klasy na znacznik etykiety elementu formularza przy użyciu właściwości interfejsu API formularza. Możesz jednak ustawić prefiks i sufiks, aby zawinąć element (etykieta + obszar tekstowy) i użyć zagnieżdżonego selektora CSS, aby osiągnąć to, co próbujesz zrobić.

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

a w CSS możesz wybrać tag etykiety w następujący sposób:

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

Nie jest to dobre rozwiązanie, ale zwykle tak to robię i widziałem, jak robią to inni. #attributesjest dla samego elementu wejściowego, więc poprawny kod dodaje myClassklasę do textarea.

AyeshK
źródło
7

Ten post na StackOverflow mówi, że interfejs API Drupal Form nie obsługuje dodawania klas do etykiet, ale zawiera przyzwoite obejście:

Zamiast tego możesz celować za pomocą klasy opakowania dla pola i etykiety:

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

Dokumentacja interfejsu API dla theme_form_element_label () pokazuje, dlaczego etykiety nie są możliwe (przynajmniej nie po wyjęciu z pudełka): tablica atrybutów jest inicjowana w funkcji motywu i zapełniana tylko dwiema opcjonalnymi klasami („opcja” i „element” -niewidoczny').

Czy to jest całkowicie niemożliwe? Właściwie myślę, że da się to zrobić, ale muszę dodać, że sam tego nie próbowałem. Możesz spróbować:

  • Dodaj nową #label_attributeswłaściwość do niektórych (lub wszystkich) elementów formularza za pomocą hook_element_info_alter () w module niestandardowym;
  • Zastąp theme_form_form_element_label () i spraw, by scalił $attributestablicę z wartością $element['#label_attributes'].

Jeśli chcesz spróbować, daj nam znać, czy zadziałało.

marcvangend
źródło
Ze względu na ograniczenia czasowe wybiorę łatwiejsze rozwiązanie zaproponowane przez Ayesh K. Wygląda to jednak na dobre rozwiązanie, może pomóc komuś innemu. +1
Shawn
Plus 1 za wzmiankę o funkcji motywu theme_form_element_label ()
Ideogram
Obejścia: jeśli wymaganie JS na stronie jest dopuszczalne, poprawienie DOM jest prawdopodobnie najłatwiejsze. Jeśli nie, innym (średnim) sposobem byłoby usunięcie '#title'lub ustawienie, '#title_display' => 'invisible'a następnie po prostu zrobienie tego '#suffix' => '<label for="TheElementId" class="option">Display This Text</label>'. To powoduje, że pojawia się poza opakowaniem, które <div>Drupal używa do wprowadzania danych do formularza, ale reguła CSS może sprawić, że nie będzie wyglądać inaczej.
SeldomNeedy
2

Rozwijając odpowiedź Ayesh, zamieściłem przykładowy przypadek użycia takiego kodu. Podczas gdy odpowiedź marvangend to znacznie więcej Drupalesk, to jest dużo kopania dla bardzo prostego wyniku. Łączenie specyficznych elementów formularza i CSS w pakiecie ze wspomnianą formą jest ogólnym przypadkiem użycia, pozwalając nam celować i działać na elementach wewnętrznych jest nieco bardziej konkretny.

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
źródło
2

Na Drupal 8 zrób to, dodając plik 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']
    );
  }
}

i dodaj #label_attributes przy tworzeniu formularza:

$form['some_field'] = [
  [...]
  '#label_attributes' => [
    'some_attr' => 'some_value',
  ]
]
vibby
źródło
0

Znalazłem stosunkowo łatwy sposób, aby to osiągnąć za pomocą modułu Fences D7. Ten moduł zawiera wiele plików szablonów do dostosowania pól. Edytuj pole, któremu chcesz nadać unikalną klasę, i zmień znacznik opakowania na coś odpowiedniego dla siebie. Następnie znajdź odpowiedni plik szablonu w module i skopiuj go do swoich witryn / all / themes / THEME_NAME.

Przed

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

Po

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

Po dodaniu <?php print $label; ?>drukuje nazwę pola jako klasę, umożliwiając kierowanie na wszystkie etykiety pól indywidualnie. Mam nadzieję, że to pomaga komuś innemu!

sen2008
źródło
0

Jest brudny, ale możesz dodać HTML do właściwości „# title”:

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

Jestem zaskoczony, że to działa. Sądzę, że Drupal to odfiltruje, ale nie. Możesz więc owinąć etykietę inną klasą:

<label for="edit-m-vernacularname" class="inline"><span title="HELP!">Common name
</span> </label>
Ideogram
źródło