Цветовая палитра из коробки Drupal

Цветовая палитра из коробки Drupal

При написании модуля мне потребовалось создать настройки для указания цвета для html кнопки. Пользователь из админки модуля должен был иметь возможность менять цвет, не вмешиваясь в css стили. Естественно, записывать цвета по памяти в формате #FFFFFF или #FF0000 абсолютно неудобно - нужно использовать палитру. При изучении данного вопроса, оказалось, что далеко ходить не нужно и Drupal уже имеет все необходимое в своем инструментарии.
Для демонстрации такой возможности создадим простенький интерфейс настроек.
В MYMODULE.module опишем хук меню.

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * Implements hook_menu().
 */
function MYMODULE_menu() {
  $items['colorwheel'] = array(
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MYMODULE_colorwheel_page'),
    // Доступ открыт всем, т.к. это экспериментальный модуль.
    'access callback' => TRUE,
  );
 
  return $items;
}

Структура страницы настроек содержит минимальное количество элементов. В данном случае необходимо хранить только один цвет, поэтому вполне можно обойтись переменными в качестве хранилища данных. Для этого используем функцию system_settigs_form() в MYMODULE_colorwheel_page().

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
/**
 * Color wheel settings page.
 */
function MYMODULE_colorwheel_page() {
  // Подключаем файл js.
  $path = drupal_get_path('module', 'MYMODULE');
  $form['#attached']['js'][]  = $path . '/js/MYMODULE.js';
 
  // Библиотека farbtastic отвечает за отображение палитры и выбор цвета.
  $form['#attached']['library'][] = array('system', 'farbtastic');
 
  // Филдсет настроек.
  $form['wrapper'] = array(
    '#type' => 'fieldset',
    '#title' => t('Color settings'),
  );
 
  $form['wrapper']['colorwheel_bg'] = array(
    '#type'   => 'textfield',
    '#size'   => 8,
    '#prefix' => '<div><div class="colorwheel-farbtastic"></div>',
    '#suffix' => '</div>',
    '#default_value' => variable_get('colorwheel_bg', ''),
    '#description' => t('Background color'),
    // Валидация кода цвета.
    '#element_validate' => array('colorwheel_color_validate'),
  );
 
  return system_settings_form($form);
}

Функция colorwheel_color_validate() отвечает за валидацию цвета, чтобы пользователь не смог сохранить некорректные значения.

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * Validate color.
 */
function colorwheel_color_validate($element) {
  // Получаем код цвета.
  $value = $element['#value'];
  preg_match('/#([a-f]|[A-F]|[\d]){3}(([a-f]|[A-F]|[\d]){3})?\b/', $value, $match);
 
  // Если совпадений с регулярным выражением нет - отображаем ошибку.
  if (empty($match[0])) {
    form_error($element, t('Please enter the valid color (use color wheel).'));
  }
}

Добавим background color к элементу формы textfield с таким расчетом, чтобы цвет заливки совпадал с цветом, выбранным с помощью палитры. Поскольку цвет букв в текстовом поле черный, то при выборе черного цвета через палитру текст не будет различим. Было бы неплохо сделать инверсию цвета при использовании палитры. Добавим в js файл также функцию инверсии цвета invertColor.
Файл MYMODULE.js (расположен по пути MYMODULE/js/MYMODULE.js) содержит следующий код

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
41
42
43
44
45
46
47
(function ($) {
  /**
   * Color wheel js functions.
   */
  Drupal.behaviors.MYMODULE = {
    attach: function(context, settings) {
      var current = this;
 
      // Инициализируем переменные.
      var div = $("div.colorwheel-farbtastic", context),
        input = $('input.form-text', div.parent()),
        farb  = $.farbtastic(div),
        color = input.val();
 
      // Устанавливаем ранее сохраненный цвет.
      if (color != '') {
        farb.setColor(color);
        input.css({
          'background-color': color,
          'color': current.invertColor(color)
        });
      }
 
      // "Привязываем" изменение положение маркера на палитре с текстовым полем.
      farb.linkTo(function(color) {
        input.css({
          'background-color': color,
          color: current.invertColor(color)
        }).val(color);
      });
 
      // Если вставляем код цвета из буфера напрямую в текстовое поле - устанавливаем такой же цвет для палитры.
      input.unbind().bind('keyup change', function() {
        farb.setColor($(this).val());
      });
    },
    // Инверсия цвета.
    invertColor: function (inputcolor) {
      var color = inputcolor.substring(1);
      color = parseInt(color, 16);
      color = 0xFFFFFF ^ color;
      color = color.toString(16);
      color = ("000000" + color).slice(-6);
      return "#" + color;
    }
  };
})(jQuery);

В результат получаем вот такую страницу настроек
farbtastic палитра
Далее сохраненный в переменной цвет можно использовать в темирующей функции либо непосредственно в html.