Como posso adicionar uma classe a um rótulo?

8

Eu preciso adicionar um nome de classe a determinados rótulos criados pela API de formulário do Drupal, como esta:

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

Se eu usar o seguinte, o <textarea>obtém uma classe, mas não o rótulo.

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

Estou procurando algo semelhante que adicione uma classe ao <label>.

Shawn
fonte
Você também deve considerar se você já não pode direcionar esse rótulo de campo com CSS usando a classe de contêiner pai para o nome do campo, por exemplo.field-name-field-myfield label{ color:red; }
David Thomas

Respostas:

6

Você não pode definir uma classe para a tag label do elemento do formulário usando as propriedades da API do formulário. No entanto, você pode definir um prefixo e um sufixo para agrupar o elemento (label + textarea) e usar algum seletor CSS aninhado para realizar o que você está tentando fazer.

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

e no CSS, você pode selecionar a tag label assim:

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

Não é uma solução decente, mas é assim que costumo fazer isso e tenho visto outros. #attributesé para o próprio elemento de entrada, portanto, é correto que seu código adicione a myClassclasse ao textarea.

AyeshK
fonte
7

Esta publicação no StackOverflow diz que a API Drupal Form não suporta a adição de classes aos rótulos, mas contém uma solução decente:

Em vez disso, você pode direcioná-lo usando a classe wrapper para o campo e o rótulo:

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

A documentação da API para theme_form_element_label () mostra por que os rótulos não são possíveis (pelo menos não prontos para uso ): a matriz de atributos é inicializada na função theme e preenchida com apenas duas classes opcionais (elemento 'option' e ' -invisível').

Então, é completamente impossível? Na verdade, acho que pode ser feito, mas devo acrescentar que não tentei isso sozinho. Você pode tentar:

  • Adicione uma nova #label_attributespropriedade a alguns (ou todos) elementos do formulário usando hook_element_info_alter () em um módulo personalizado;
  • Substitua theme_form_element_label () e faça com que ele mescle a $attributesmatriz com o valor de $element['#label_attributes'].

Se você tentar fazer isso, informe-nos se funcionou.

Marcvangend
fonte
Devido a restrições de tempo, irei para a solução mais fácil proposta por Ayesh K. Essa parece ser uma boa solução, mas pode ajudar outra pessoa. +1
Shawn
Mais 1 para mencionar a função tema theme_form_element_label ()
Ideogram
Soluções alternativas: se a exigência de JS no site for aceitável, ajustar o DOM provavelmente será mais fácil. Caso contrário, outra maneira (média) seria remover '#title'ou definir '#title_display' => 'invisible'e apenas fazer '#suffix' => '<label for="TheElementId" class="option">Display This Text</label>'. Isso faz com que apareça fora do wrapper que o <div>Drupal usa para seus elementos de entrada de formulário, mas uma regra CSS pode fazer com que não pareça diferente.
SeldomNeedy
2

Expandindo a resposta de Ayesh, incluí um exemplo de caso de uso para esse código. Enquanto a resposta de marvangend é muito mais Drupalesk, é muito difícil encontrar um resultado muito simples. Manter os elementos específicos do formulário e CSS agrupados com o referido formulário é o caso de uso geral, permitindo-nos direcionar e agir sobre elementos internos é um pouco mais 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
fonte
2

No Drupal 8, faça isso simplesmente adicionando o arquivo 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']
    );
  }
}

e adicione #label_attributes na criação do formulário:

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

Encontrei uma maneira relativamente fácil de fazer isso usando o módulo Fences D7. Este módulo vem com muitos arquivos de modelo para personalizar os campos. Edite o campo ao qual você deseja atribuir uma classe exclusiva e altere a marcação do wrapper para algo relevante para você. Depois disso, encontre o arquivo de modelo correspondente no módulo e copie-o em seus sites / all / themes / THEME_NAME.

Antes

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

Depois de

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

Ao adicionar <?php print $label; ?>, ele imprime o nome do campo como uma classe, permitindo segmentar todos os rótulos de campo individualmente. Espero que isto ajude alguém!

sen2008
fonte
0

Está sujo, mas você pode adicionar HTML à propriedade '# title':

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

Estou surpreso que funcione. Eu acho que Drupal filtraria isso, mas não. Então, você pode envolver o rótulo com outra classe:

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