web-dev-qa-db-fra.com

Ajouter des classes au formulaire de sélection de l'option

Comment puis-je ajouter des classes à une balise d'option de formulaire sans JS? Pour le moment dans Form API, je peux passer un tableau à clés comme celui-ci

array(
  '0' => 'option 0',
  '1' => 'option 1',
)

et je vais avoir du HTML comme ça

<option value="0">option 0</option>
<option value="1">option 1</option>

Y a-t-il un moyen de faire quelque chose comme ça:

array(
  array(
    'value' => 0,
    'text' => 'option 0',
    'class' => 'bob 0',
  ),
  array(
    'value' => 1,
    'text' => 'option 1',
    'class' => 'bob 1',
  ),
)

puis obtenez ceci

<option value="0" class="bob 0">option 0</option>
<option value="1" class="bob 1">option 1</option>
18
Paul Sheldrake

Je n'ai donc pas pu obtenir l'option entièrement flexible, mais voici un moyen d'ajouter des classes à la balise options en fonction de la valeur de l'option. Cela fonctionne mais en remplaçant le theme_select fonction pour utiliser ma propre version de form_select_options

// theme_select
function THEME_select($variables) {
  $element = $variables['element'];
  element_set_attributes($element, array('id', 'name', 'size'));
  _form_set_class($element, array('form-select'));
  return '<select' . drupal_attributes($element['#attributes']) . '>' . THEME_form_select_options($element) . '</select>';
}

/**
 *
 * @param type $element
 * @param type $choices
 * @return string 
 */
function THEME_form_select_options($element, $choices = NULL) {
  if (!isset($choices)) {
    $choices = $element['#options'];
  }
  // array_key_exists() accommodates the rare event where $element['#value'] is NULL.
  // isset() fails in this situation.
  $value_valid = isset($element['#value']) || array_key_exists('#value', $element);
  $value_is_array = $value_valid && is_array($element['#value']);
  $options = '';
  foreach ($choices as $key => $choice) {
    if (is_array($choice)) {
      $options .= '<optgroup label="' . $key . '">';
      $options .= THEME_form_select_options($element, $choice);
      $options .= '</optgroup>';
    }
    elseif (is_object($choice)) {
      $options .= THEME_form_select_options($element, $choice->option);
    }
    else {
      $key = (string) $key;
      if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
        $selected = ' selected="selected"';
      }
      else {
        $selected = '';
      }
      $options .= '<option class="' . drupal_clean_css_identifier($key) . '"  value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>';
    }
  }
  return $options;
}
5
Paul Sheldrake

Malheureusement, ce n'est pas très facile actuellement d'utiliser l'API Form.

Il y a un problème ouvert pour ajouter cette fonctionnalité (cela remonte à 2008) qui vous permettrait théoriquement de faire quelque chose comme ceci:

$form['optiontest'] = array(
  '#type' => 'select',
  '#title' => t('Option test'),
  '#options' => array(
    array(
      '#return_value' => 0,
      '#value' => t('First option'),
      '#attributes' => array('class' => 'first', 'title' => t('First option')),
    ),
    array(
      '#value' => t('Option group'),
      '#attributes' => array('class' => 'group', 'title' => t('This is an optgroup')),
      '#options' => array(
        array('#return_value' => 2, '#value' => t('1st sub-option')),
        array('#return_value' => 4, '#value' => t('2nd sub-option')),
      ),
    ),
  ),
);

Mais malheureusement, il n'y a rien d'autre que des correctifs échoués attachés au problème pour le moment.

La seule façon dont je peux penser pour le moment serait d'ajouter un #process fonction à l'élément select, et ajoutez la ou les classes à chaque option lorsqu'elles sont décomposées individuellement.

8
Clive

Il existe en fait un moyen de remplacer les éléments option individuels. Cependant, je ne sais pas si cela fonctionne en Drupal 7.

Voici du code qui fonctionne en Drupal 8. Cela vaut peut-être la peine d'être essayé.

$form['select'] = [
  '#type' => 'select',
  '#title' => t('Select'),
  '#options' => [
    '0' => t('Bob 0'),
    '1' => t('Bob 1'),
  ],
  // You define attributes for individual options as follows.
  '0' => [
    // I have tried 'disabled' = TRUE and it works.
    'disabled' => TRUE,
    // I have never tried #attributes, but I think it should work.
    '#attributes' => [
      'class' => ['bob-0'],
    ],
  ]
]

J'espère que ça aide. À votre santé! Sinon, optez pour l'une des autres solutions.

0
Jigarius