web-dev-qa-db-fra.com

Comment thématiser des éléments de formulaire Web (boutons radio, etc.)?

Je voudrais savoir comment thématiser Drupal 7 Webform éléments? Je veux changer la structure HTML de chaque élément, pas simplement envelopper le formulaire avec div ou quelque chose comme ça. Et je veux laisser les éléments du thème tels quels.

EDIT: Je voudrais ajouter une classe à l'étiquette et un bouton radio de type d'entrée.

3
gregab

Chaque élément de formulaire Web possède son propre fichier dans le sous-répertoire "composants" du dossier du module de formulaire Web.

Si vous regardez dans ces fichiers, il existe une fonction _webform_theme_COMPONENTTYPE (), par exemple _ webform_theme_date () pour les champs de date.

Cette fonction définit les fonctions de thème pour ce type de champ.

Ces fonctions de thème sont ce que vous pouvez utiliser pour remplacer le thème des champs.

Par exemple, theme_webform_date () peut être remplacé par THEMENAME_webform_date (variables & $) et vous pouvez modifier la sortie.

Si ce sont des éléments tels que les wrappers de champ ou les étiquettes que vous souhaitez, essayez de remplacer la fonction theme_webform_element () .

Cela vous permettra de faire des choses comme changer l'endroit où l'étiquette est imprimée par rapport au champ.

Vous pouvez utiliser $element['#type'] pour distinguer des types de champs spécifiques dans cette fonction de thème.

Remarque: Les composants Webform sont un cas spécial. Normalement, vous pouvez trouver des choses à thème en regardant dans la fonction MODULENAME_theme (). Dans ce cas webform_theme () .

Plus précisément, pour définir des classes sur les champs des boutons radio:

Votre exigence d'ajouter la classe à un bouton radio est malheureusement un peu différente. C'est parce que le formulaire Web n'utilise pas son propre thème, il utilise drupal core's

Donc, ce que vous voulez, c'est theme_radios () et/ou theme_radio () et/ou theme_form_element_label () .

Quelque chose comme ça (il y a des commentaires pour vous dire ce qui a changé):

/**
 * Theme a set of radio buttons.
 */
function THEMENAME_radios($variables) {
  $element = $variables['element'];
  $attributes = array();
  if (isset($element['#id'])) {
    $attributes['id'] = $element['#id'];
  }
  $attributes['class'] = 'form-radios';
  if (!empty($element['#attributes']['class'])) {
    $attributes['class'] .= ' ' . implode(' ', $element['#attributes']['class']);
  }
  if (isset($element['#attributes']['title'])) {
    $attributes['title'] = $element['#attributes']['title'];
  }

  // Add custom classes.
  // To target specific elements you can use the $element variable.
  // You can target the label using:
  // .your-custom-class label
  $attributes['class'] .= 'your-custom-class another-custom-class';

  return '<div' . drupal_attributes($attributes) . '>' . (!empty($element['#children']) ? $element['#children'] : '') . '</div>';
}

/**
 * Theme a single radio button.
 */
function THEMENAME_radio($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'radio';
  element_set_attributes($element, array('id', 'name','#return_value' => 'value'));

  if (isset($element['#return_value']) && $element['#value'] !== FALSE && $element['#value'] == $element['#return_value']) {
    $element['#attributes']['checked'] = 'checked';
  }
  _form_set_class($element, array('form-radio'));

  // Set custom classes.
  // Use $element to target specific fields.
  $element['#attributes']['class'][] = 'your-custom-class';
  $element['#attributes']['class'][] = 'another-custom-class';

  return '<input' . drupal_attributes($element['#attributes']) . ' />';
}

Malheureusement, il n'est pas possible d'ajouter des classes à une étiquette, sauf pour remplacer theme_form_element_label () à cause de ce bogue .

Il existe deux façons possibles de résoudre ce problème dans la couche de thème.

La première consiste à ajouter la classe à l'encapsuleur de champ, puis à cibler les étiquettes via celle de votre CSS ou JS.

L'autre consiste à remplacer theme_form_element_label () comme ceci:

/**
 * Theme a form element label.
 */
function THEMENAME_form_element_label($variables) {
  $element = $variables['element'];
  // This is also used in the installer, pre-database setup.
  $t = get_t();

  // If title and required marker are both empty, output no label.
  if ((!isset($element['#title']) || $element['#title'] === '') && empty($element['#required'])) {
    return '';
  }

  // If the element is required, a required marker is appended to the label.
  $required = !empty($element['#required']) ? theme('form_required_marker', array('element' => $element)) : '';

  $title = filter_xss_admin($element['#title']);

  $attributes = array();
  // Style the label as class option to display inline with the element.
  if ($element['#title_display'] == 'after') {
    // Changed to make class an array.
    $attributes['class'][] = 'option';
  }
  // Show label only to screen readers to avoid disruption in visual flows.
  elseif ($element['#title_display'] == 'invisible') {
    // Changed to make class an array.
    $attributes['class'][] = 'element-invisible';
  }

  if (!empty($element['#id'])) {
    $attributes['for'] = $element['#id'];
  }

  // Add your classes here.
  // If you are using variables to make the class use the drupal_html_class()
  // function.
  // To target specific elements you can use the $element variable.
  // For example, based on field type:
  if ($element['#type'] == '') {
    $attributes['class'][] = 'your-custom-class';
    $attributes['class'][] = 'another-custom-class';
  }

  // The leading whitespace helps visually separate fields from inline labels.
  return ' <label' . drupal_attributes($attributes) . '>' . $t('!title !required', array('!title' => $title, '!required' => $required)) . "</label>\n";
}
18
rooby