Делаем AJAX-кнопку с HTML-значением
Form API у Drupal - прекрасен. Любая форма собирается "на УРА".
Но, все же есть недостатки...
По умолчанию, для всех кнопок, Drupal использует HTML-элемент input, а он, не поддерживает вставку HTML-содержимого в значение. Это очень удобная фича для создания красочных кнопок, например с иконками. Ею можно пользоваться с помощью HTML-элемента button.
Есть несколько финтов ушами (о них тоже расскажу) с помощью которых можно соорудить кнопку (button) из FAPI. Но они исключают важную, на мой взгляд, особенность - они не работают с AJAX'ом.
Далее приведу рецепт победы над этим недугом.
Простая кнопка
Сначала, как обещал, простой вариант вывода кнопки:
$form['my_button'] = array(
'#prefix' => '<button type="submit">',
'#suffix' => '</button>',
'#markup' => '<i class="my-icon-class"></i>',
);
Как видите - все просто. Добавляем элемент с разметкой, назначаем ему суффикс и префикс, и мостим туда всю нужную разметку.
Такой-себе костылик...
Кнопка с AJAX-обработчиком
Теперь рассмотрим как сделать "правильную" кнопку, в которой все будет работать.
Конечно же, мы будем переопределять.
Переопределять мы будем темизацию кнопок. По умолчанию, определена в файле form.inc, находящегося в папке includes. Вот содержание функции:
/**
* Returns HTML for a button form element.
*
* @param $variables
* An associative array containing:
* - element: An associative array containing the properties of the element.
* Properties used: #attributes, #button_type, #name, #value.
*
* @ingroup themeable
*/
function theme_button($variables) {
$element = $variables['element'];
$element['#attributes']['type'] = 'submit';
element_set_attributes($element, array('id', 'name', 'value'));
$element['#attributes']['class'][] = 'form-' . $element['#button_type'];
if (!empty($element['#attributes']['disabled'])) {
$element['#attributes']['class'][] = 'form-button-disabled';
}
return '<input' . drupal_attributes($element['#attributes']) . ' />';
}
В файле template.php, нужной темы, определяем функцию в которой будем использовать новое свойство кнопок - #htmlbutton. Вот код:
/**
* Returns HTML for a button form element.
*
* @param $variables
* An associative array containing:
* - element: An associative array containing the properties of the element.
* Properties used: #attributes, #button_type, #name, #value, #htmlbutton.
*/
function THEME_NAME_button($variables) {
$element = $variables['element'];
$element['#attributes']['type'] = 'submit';
element_set_attributes($element, array('id', 'name', 'value'));
$element['#attributes']['class'][] = 'form-' . $element['#button_type'];
if (!empty($element['#attributes']['disabled'])) {
$element['#attributes']['class'][] = 'form-button-disabled';
}
// Добавим дополнительную проверку нового свойства
// и в зависимости от его наличия будем выводить нужный тип кнопки
if (isset($element['#htmlbutton']) && $element['#htmlbutton']) {
$value = $element['#value'];
unset($element['#attributes']['value']);
return '<button' . drupal_attributes($element['#attributes']) . '>' . $value . '</button>';
}
else {
return '<input' . drupal_attributes($element['#attributes']) . ' />';
}
}
Не забываем заменить "THEME_NAME" на имя темы, и сбросить кеш.
Теперь, для вывода кнопки с HTML нужно добавить свойство #htmlbutton, и все это может работать с AJAX'ом:
$form['my_button'] = array(
'#type' => 'button',
'#htmlbutton' => TRUE, // Наше новое свойство
'#value' => '<i class="my-icon-class"></i>',
'#ajax' => array(
'callback' => 'my_ajax_callback',
),
);
Все остальные кнопки будут выводится как положено - INPUT'ами.
Переопределяем все кнопки
Если нужно переопределить абсолютно все кнопки на сайте, можно сделать следующим способом:
function MY_THEME_button($variables) {
$element = $variables['element'];
$label = $element['#value'];
element_set_attributes($element, array('id', 'name', 'value', 'type'));
$element['#attributes']['class'][] = 'form-' . $element['#button_type'];
if (!empty($element['#attributes']['disabled'])) {
$element['#attributes']['class'][] = 'form-button-disabled';
}
return '<button' . drupal_attributes($element['#attributes']) . '>'. $label .'</button>';
}
И не нужно будет менять или добавлять новые свойства кнопкам.
Примерно таким же образом переопределяются кнопки в Bootstrap-темах.
Комментарии