Вот такая штукенция получилась. Radios Select для Drupal 7.

История из разряда “Новая жизнь старых вещей”. Точнее – новая “шуба” для привычного элемента форм radios. Для тех случаев, когда элемент radios строится из модуля.

Собственно, началось всё с того, что искал способ отобразить в форме модуля некую таблицу символов с возможностью выбора любого одного символа. Символы должны быть достаточно крупные (шрифт где-то 18-20px). Для начала попытался приспособить обычный select, но не понравилось: во-первых, список слишком длинный и выбирать неудобно, а во-вторых, добиться единообразного отображения (размер шрифта, padding, выравнивание и т.д.) в разных браузерах оказалось совсем непросто.

В общем, нужно было искать более компактное решение, при котором таблица была бы именно таблицей. В процессе разных тестов случайно обнаружил, что метки (label) для элемента radios в большинстве браузеров обрабатывают клики как и родительский (связанный с меткой) сам radios-control (кружочек, по которому мы тыкаем мышкой). То есть – по клику на метку элемент устанавливается в состояние checked, как если б мы кликали на сам кружочек. Не бог весть какое открытие, но беглый поиск в гугле аналогичных развитых решений с использованием меток ничего не дал. И я приступил к работе.

После ряда тычков в неверных направлениях было выведено более-менее унифицированное и кроссбраузерное решение (CSS + jQuery). Я его назвал Radios Select. Вот оно, со скромной гордостью и удовлетворением представляю своё детище:

А вот что происходит по клику на элементе:

Код, формирующий вывод:

<?php
$values = preg_split('/[\s,\.]+/', ucwords('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sodales congue velit. Duis commodo interdum ipsum.'));

$form['rs_example_1']['radios_select_1'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select word:'),
  '#default_value' => 1,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#description'   => t('Word to use in form.'),
);
?>

Собственно, Radios Select можно использовать не только, как таблицу символов, а для выбора любого значения: строки, числа. Родилась идея сделать модуль-хук, который бы темизировал элементы radios как Radios Select, если у элементов установлен соответствующий параметр, а иначе – выводил бы стандартный radios. В процессе работы над модулем элемент Radios Select “оброс” рядом параметров, позволяющих кастомизировать вывод этого псевдо-элемента (это действительно скорее псевдо-элемент, поскольку по факту строится обычный radios и последующая обработка в submit’е – типичная для radios).

Например, можно изменить свойства шрифта элемента:


<?php
$values = preg_split('/[\s,\.]+/', ucwords('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sodales congue velit. Duis commodo interdum ipsum.'));

$form['rs_example_2']['radios_select_2'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select word:'),
  '#default_value' => 2,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'label'         => array(
      'font'         => 'Times New Roman',  // this sets font family (same as in CSS way)
      'font_size'    => 1.4,              // this sets font size (in "units" units)
      'font_color'   => '#339933',        // this sets font color (same as in CSS way)
      'line_height'  => 2,                // this sets line height (in "units" units)
      'units'        => 'em',             // can be em or px (default: px)
    ),
  ),
  '#description'   => t('Word to use in form.'),
);
?>

А вот и вариант для искомой таблицы символов:


<?php
$values = array();
for ($i = 33; $i < 256; $i++) {
  $values[] = '&#' . $i . ';';
}
$values = array_combine($values, $values);

// Replace Soft Hyphen symbol (&#173;) by non-breaking space
// (this symbol produces row break in Firefox and Opera)
$values['&#173;'] = '&nbsp;';

$form['rs_example_3']['radios_select_3'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select symbol:'),
  '#default_value' => '&#169;',
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'label'          => array(
      'width'          => 2,      // sets label width (in "units" units)
      'height'         => 2,      // sets label height (in "units" units)
      'line_height'    => 2,
      'padding_x'      => '3px',  // horizontal padding (we use px instead of units)
      'padding_y'      => '3px',  // vertical padding (we use px instead of units)
      'units'          => 'em',
    ),
  ),
  '#description'   => t('Symbol to use in form.'),
);
?>

Можно “подкрасить” оформление элемента (выбирается также светлая или тёмная стрелка):


<?php
$values = array_merge(range('A', 'Z'), range('a', 'z'));

$form['rs_example_4']['radios_select_4_1'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select character:'),
  '#default_value' => 2,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'element'        => array(
      'frame_color'    => '#d4d0c8', // this sets frame color
      'dark_arrow'     => TRUE,      // this sets dark arrow for this element
     ),
    'label'          => array(
      'width'          => 2,
      'height'         => 2,
      'padding_x'      => '3px',
      'padding_y'      => '3px',
      'units'          => 'em',
     ),
   ),
  '#description'   => t('Character to use in form.'),
);
?>

Или убрать фон выбранного элемента и объединить с селектором (так называемый hollow-режим):


<?php
$values = array_merge(range('A', 'Z'), range('a', 'z'));

$form['rs_example_4']['radios_select_4_2'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select character:'),
  '#default_value' => 2,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'element'         => array(
      'hollow'          => TRUE,   // this sets hollow mode
     ),
    'label'         => array(
      'width'           => 2,
      'height'          => 2,
      'padding_x'       => '3px',
      'padding_y'       => '3px',
      'units'           => 'em',
     ),
   ),
  '#description'   => t('Character to use in form.'),
);
?>

А можно и вставить картинки в селектор, причём выровнять по желанию – либо по верху (по умолчанию), либо по низу (как в этом примере):


<?php
$module_path = url(drupal_get_path('module', 'radios_select'));
$images_path = $module_path . '/examples/images/';

$values = array(
  '<img src="' . $images_path . 'image1.png" /><br />Some image 1',
  '<img src="' . $images_path . 'image2.png" /><br />Some image 2',
  '<img src="' . $images_path . 'image3.png" /><br />Some image 3',
  '<img src="' . $images_path . 'image1.png" /><br />Some image 4',
  '<img src="' . $images_path . 'image2.png" /><br />Some image 5',
  '<img src="' . $images_path . 'image3.png" /><br />Some image 6',
);

$form['rs_example_5']['radios_select_5_1'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select image:'),
  '#default_value' => 0,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'label'         => array(
      'valign'        => 'bottom', // this sets vertical alignment of labels to bottom
      'font_size'     => 12,
      'line_height'   => 14,
      'padding_x'     => 4,
      'padding_y'     => 4,
     ),
   ),
  '#description'   => t('Select horizontal or vertical image.'),
);
?>

Другой вариант с картинками – выравнивание “в ряд” с текстом метки (можно также задать произвольный vertical-align для изображения, как обычно в CSS, здесь, в примере – просто смещение от базовой линии):


<?php
$module_path = url(drupal_get_path('module', 'radios_select'));
$images_path = $module_path . '/examples/images/';

$values = array(
  '<img src="' . $images_path . 'ru.png" /> Russian Federation',
  '<img src="' . $images_path . 'us.png" /> USA',
  '<img src="' . $images_path . 'ca.png" /> Canada',
  '<img src="' . $images_path . 'fr.png" /> France',
  '<img src="' . $images_path . 'de.png" /> Germany',
  '<img src="' . $images_path . 'it.png" /> Italy',
  '<img src="' . $images_path . 'gb.png" /> United Kingdom',
  '<img src="' . $images_path . 'gr.png" /> Greece',
  '<img src="' . $images_path . 'tr.png" /> Turkey',
  '<img src="' . $images_path . 'ua.png" /> Ukraine',
  '<img src="' . $images_path . 'no.png" /> Norway',
);

$form['rs_example_5']['radios_select_5_2'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select country:'),
  '#default_value' => 0,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'label'         => array(
      'img_valign'    => '-4px',        // sets vertical alignment of images
      'nowrap'        => 'TRUE',        // disables word wrapping for text in labels
     ),
   ),
  '#description'   => t('Country from where you are.'),
);
?>

А можно упорядочить метки в колонки (любое количество колонок):

<?php
$module_path = url(drupal_get_path('module', 'radios_select'));
$images_path = $module_path . '/examples/images/';

$values = array(
  '<img src="' . $images_path . 'ru.png" /> Russian Federation',
  '<img src="' . $images_path . 'us.png" /> USA',
  '<img src="' . $images_path . 'ca.png" /> Canada',
  '<img src="' . $images_path . 'fr.png" /> France',
  '<img src="' . $images_path . 'de.png" /> Germany',
  '<img src="' . $images_path . 'it.png" /> Italy',
  '<img src="' . $images_path . 'gb.png" /> United Kingdom',
  '<img src="' . $images_path . 'gr.png" /> Greece',
  '<img src="' . $images_path . 'tr.png" /> Turkey',
  '<img src="' . $images_path . 'ua.png" /> Ukraine',
  '<img src="' . $images_path . 'no.png" /> Norway',
);

$form['rs_example_6']['radios_select_6'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select country:'),
  '#default_value' => 0,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'element'         => array(
      'columns'         => 4,       // this sets ordering by 4 columns
    ),
    'label'         => array(
      'img_valign'      => -4,      // px by default, so we can skip units
      'nowrap'          => 'TRUE',
     ),
   ),
  '#description'   => t('Country from where you are.'),
);
?>

Наконец, труъ-программисты могут полностью изменить вид Radios Select с помощью CSS (стили аттачатся “на лету”, при создании элемента):


<?php
$module_path = url(drupal_get_path('module', 'radios_select'));
$images_path = $module_path . '/examples/images/';

$values = array(
  '<img src="' . $images_path . 'ru.png" /> Russian Federation',
  '<img src="' . $images_path . 'us.png" /> USA',
  '<img src="' . $images_path . 'ca.png" /> Canada',
  '<img src="' . $images_path . 'fr.png" /> France',
  '<img src="' . $images_path . 'de.png" /> Germany',
  '<img src="' . $images_path . 'it.png" /> Italy',
  '<img src="' . $images_path . 'gb.png" /> United Kingdom',
  '<img src="' . $images_path . 'gr.png" /> Greece',
  '<img src="' . $images_path . 'tr.png" /> Turkey',
  '<img src="' . $images_path . 'ua.png" /> Ukraine',
  '<img src="' . $images_path . 'no.png" /> Norway',
);

$form['rs_example_7']['radios_select_7'] = array(
  '#type'          => 'radios',
  '#title'         => t('Select country:'),
  '#default_value' => 0,
  '#options'       => $values,
  '#radios_select' => TRUE,     // enables Radios Select for this radios element
  '#rs_attributes' => array(
    'element'         => array(
      'columns'         => 4,
      'css'             => array(
        'div.type-radios-current {background: #222 url("'. $images_path . 'custom_bg.png") bottom right no-repeat; border-color: #222 !important;}',
        'div.type-radios-current .inner {background: #a8a8a8;}',
        'div.type-radios-current label  {background: #ffc136 url("'. $images_path . 'custom_label_active.png") center center repeat-x !important; border: 1px solid #c35e22 !important; color: black;}',
        'div.rs_opened {background: #222 url("'. $images_path . 'custom_bg_active.png") bottom right no-repeat;}',
        'div.rs_opened .inner {background: none;}',
        'div.type-radios-select {background: #d0d0d0 url("'. $images_path . 'custom_select_bg.png") top center repeat-x !important; border-color: #222 !important;}',
        'div.type-radios-select label.selected {background: #ffc136 url("'. $images_path . 'custom_label_active.png") center center repeat-x !important; border: 1px solid #c35e22 !important; color: black;}',
        'div.type-radios-select label {background: #3a3a3a url("'. $images_path . 'custom_label.png") center center repeat-x !important; border: 1px solid #222 !important; color: white;}',
        'div.type-radios-select label:hover {background: #ffc136 url("'. $images_path . 'custom_label_active.png") center center repeat-x !important;}',
      ),
    ),
    'label'         => array(
      'img_valign'      => -4,
      'nowrap'          => 'TRUE',
     ),
   ),
  '#description'   => t('Country from where you are.'),
);
?>

Все эти примеры (рабочие и с исходным кодом) доступны из help’а модуля Radios Select (см. приложенный архив) по адресу: admin/help/radios_select

Internet Explorer.

В IE, как обычно, всё “не как у людей”. Начнём с того, что все “красивые” закругления в нём отсутствуют. Попытки прицепить JS-библиотеки типа PIE, curved-corner и пр. положительного результата не дали – эти надстройки ломают разметку inline-элементов.

Вторая проблема – IE единственный из браузеров, который не захотел “понимать” клики по меткам. Пришлось специально для него сделать эмуляцию клика по радиокнопке при клике на метке.

Ещё одна особенность конкретно IE6 – курсор почему-то не устанавливается в “hand” (pointer) при hover’е над метками, даже если явно указывать для него правило в CSS.

В общем, базовый функционал в IE всё же обеспечен (по крайней мере версии IE6, IE7, IE8 с Radios Select работают нормально). Но выглядит в нем всё чуть менее красиво.

Поведение при noscript.

При выключенном JS происходит следующее:

1. Скрывается контейнер выбранного (текущего) элемента – тот, который со стрелкой справа.

2. Делается видимым контейнер селектора (который содержит все элементы).

3. Становятся видимыми сами радиокнопки (слева от каждого элемента), таким образом пользователь может выбрать нужный пункт традиционным для radios образом – щёлкнув на элементе.

4. Таким образом, форматирование/оформление Radios Select в основном сохраняется, добавляются только input’ы.


Примечание: IE и здесь ведёт себя несколько отлично от других браузеров. При выключенном JS он не “признаёт” клики на вложенных в метку картинках (IMG) как клики на метке. Только если пользователь кликнул на текст метки или непосредственно на круглый элемент-радиокнопку.

Примечание: при выключенном JS input’ам присваивается свойство float: left (с тем, чтобы сохранить разметку и равные ширины при использовании колонок. Как следствие радиокнопка “уходит” с базовой линии контейнера и автоматически начинает позиционироваться от верха. Это в общем-то никак не сказывается на разных способах вывода элемента – за исключением, когда используется выравнивание по нижнему краю (как в примере с картинками выше). В этом случае кнопки будут расположены на разной высоте:

Желающие могут скачать и установить модуль. Модуль очень нуждается в тестировании под разными браузерами. Пока протестировано в GoogleChrome, Safari, Opera 11, Firefox 8, IE 6,7,8.

Если будете использовать/тестировать элемент под другими браузерами – просьба отписываться здесь о результатах (с указанием версии браузера).

Как бы и всё.

Скачать модуль Radios Select

Источник: http://www.drupal.ru/node/74267

Модуль FormSave: сохраняем отправки для любой формы

Всем привет!

Написал модуль для логирования отправок любых форм. Вы просто указываете id формы, и модуль прицепляется к ней сам. После этого, любая отправленная в форму информация будет сохранена в отдельной таблице базы данных, и в любое время ее можно будет посмотреть.

Зачем это нужно?

Вариант 1. Отслеживание введенных значений. Не всегда вся введенная в форму информация сохраняется. Бывает, что на ее основе делаются какие-либо вычисления, и в базу сохраняются только результаты этих вычислений. Если вы хотите посмотреть, что же было введено в качестве исходных данных, то этот модуль для вас.

Вариант 2. Вы разрабатываете большую, сложную форму, многоступенчатую да с аяксом. А то и не одну и не две, в рамках какого-либо проекта. Или нескольких проектов. Чтобы не писать для каждой из этих форм свой отдельный submit-хендлер, который может быть просто огромным, да и во многом одинаковым для подобных форм, вы просто прицепляете этот модуль, и всю работу по сохранению введенной информации он берет на себя. В модуле предусмотрено API для этого.

Немного подробнее можно прочитать на странице модуля  formsave (он пока в песочнице).

Немного скриншотов:

Скриншот экрана настроек

Скриншот списка отправок

Скриншот одной отправки

Если вы хотите видеть этот модуль в качестве полноценного проекта на drupal.org, отпишитесь, пожалуйста, в этой заявке на получение статуса Full project. то добро пожаловать на страницу проекта  formsave

Источник: http://www.drupal.ru/node/61297

© 2009 Обзор CMS