Добавляем атрибуты к html элементу <option>

Добавляем атрибуты к html элементу option

Как-то возникла необходимость, вывести обычный select с элементами option разных цветов, т.е. каждый элемент из выпадающего списка должен быть разукрашен тем цветом, который был объявлен в его названии. Ну что то вроде такого
select option
Собственно, функция form_select_options(), отвечающая за построение элементов option не позволяла никак в нее вмешиваться. Ничего не оставалось делать, как взять ее за основу и заюзать в своей темирующей функции.
Итак, непосредственно сама реализация. В файле MYMODULE.module определяем нашу тему, которая будет использоваться для отображения селекта.

1
2
3
4
5
6
7
8
9
10
11
/**
 * Implements hook_theme().
 */
function MYMODULE_theme() {
  return array(
    'imgcolor_select' => array(
      'render element' => 'element',
      'file' => 'MYMODULE.theme.inc',
    ),
  );
}

Затем опишем функцию theme_imgcolor_select(). В файле MYMODULE.theme.inc разместим следующие строки

1
2
3
4
5
6
7
8
9
10
/**
 * Returns HTML for a select form element.
 */
function theme_imgcolor_select($variables) {
  $element = $variables['element'];
  element_set_attributes($element, array('id', 'name', 'size'));
  _form_set_class($element, array('form-select'));
  $attributes = drupal_attributes($element['#attributes']);
  return '<select' . $attributes . '>' . MYMODULE_imgcolor_select_options($element) . '</select>';
}

Код функции theme_imgcolor_select() также заимствован от функции theme_select() с тем лишь исключением, что построением списка option занимается уже наша функция MYMODULE_imgcolor_select_options(). Здесь же, в MYMODULE.module размещаем код функции MYMODULE_imgcolor_select_options().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * Converts a select form element's options array into HTML.
 */
function MYMODULE_imgcolor_select_options($element, $choices = NULL) {
  if (!isset($choices)) {
    $choices = $element['#options'];
  }
 
  $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) && !empty($choice['#optgroup'])) {
      $options .= '<optgroup label="' . $key . '">';
      $options .= form_select_options($element, $choice);
      $options .= '</optgroup>';
    }
    elseif (is_object($choice)) {
      $options .= form_select_options($element, $choice->option);
    }
    else {
      $key = (string) $key;
      $selected = '';
      $check_value = $value_is_array && in_array($key, $element['#value']);
      if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key || $check_value)) {
        $selected = ' selected="selected"';
      }
 
      // Добавляем атрибуты.
      $attributes = '';
      if (is_array($choice)) {
        $attributes = ' ' . drupal_attributes($choice['#attributes']);
        $choice = $choice['#value'];
      }
      $attr = $selected . $attributes;
      $options .= '<option value="' . check_plain($key) . '"' . $attr . '>' . check_plain($choice) . '</option>';
    }
  }
  return $options;
}

Теперь объявим список опций с атрибутами.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function MYMODULE_imgcolor_options() {
  // Список желаемых цветов.
  $colors = array(
    'black', 'blue', 'brown',
    'gray', 'green', 'orange',
    'pink', 'purple', 'red',
    'teal', 'white', 'yellow',
  );
 
  $options = array(t('- No select -', array(), $context));
  foreach ($colors as $color) {
    $options[$color] = array(
      '#value' => $color,
      // Добавляем css класс и тут же, для наглядности, атрибут style c параметром background-color.
      // В обычном случае, конечно, все цвета лучше объявить через css стили.
      '#attributes' => array(
        'class' => array(drupal_clean_css_identifier($color)),
        'style' => array('background-color:' . $color),
      ),
    );
  }
 
  return $options;
}

И непосредственное использование при объявлении элемента в форме.

1
2
3
4
5
6
$form['imgcolor'] = array(
    '#title' => 'Image color',
    '#type' => 'select',
    '#theme' => 'imgcolor_select',
    '#options' => MYMODULE_imgcolor_options(),
  );

Дополнительная информация по статье

  1. https://api.drupal.org/api/drupal/includes!form.inc/function/form_select_options/7 - описание form_select_options().
  2. https://api.drupal.org/api/drupal/includes!form.inc/function/theme_select/7 - описание theme_select().