xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Создаём форму в виде таблицы

Опубликовано в

Формы в виде таблиц, где нужно выбрать несколько записей, довольно распространены в шестом друпале, но процесс их создания очень не простой :(

Форма-таблица на странице удаления модулей

Код, создающий по адресу example.com/form-table простую таблицу со списком нод и возможностью выбрать несколько из них:

/**
 * Реализация hook_menu()
 * Регистрируем адрес example.com/form-table и функцию которая будет генерировать по этому адресу контент
 */
function mymodule_menu() {
  $items = array();
 
  $items['form-table'] = array(
    'title' => 'Form-Table',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('mymodule_form_table'),
    'access arguments' => array('administer nodes'),
    'type' => MENU_CALLBACK,
  );
 
  return $items;
}
 
/**
 * Реализация hook_theme()
 * Регистрируем функцию темизации формы mymodule_form_table
 */
function mymodule_theme() {
  return array(
    'mymodule_form_table' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}
 
/**
 * Описание формы mymodule_form_table
 */
function mymodule_form_table() {
  // описание заголовков
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      theme('table_select_header_cell'),
      'Заголовок',
      'Дата создания',
    ),
  );
 
  // получаем список нод
  $nodes = db_query("SELECT nid, title, created FROM {node} ORDER BY created");
 
  while ($node = db_fetch_object($nodes)) {
    $options[$node->nid] = '';
    // заголовок ноды в виде ссылки
    $form['title'][$node->nid] = array('#value' => l($node->title, 'node/' . $node->nid));
    // дата создания ноды
    $form['created'][$node->nid] = array('#value' => format_date($node->created));
  }
 
  $form['nid'] = array(
    '#type' => 'checkboxes',
    '#options' => isset($options) ? $options : array(),
  );
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Удалить',
  );
 
  return $form;
}
 
 
/**
 * Темизация формы mymodule_form_table
 * Создаём ту самую таблицу
 */
function theme_mymodule_form_table($form) {
  $rows = array();
  foreach (element_children($form['nid']) as $key) {
    $rows[] = array(
      drupal_render($form['nid'][$key]),     // чекбокс
      drupal_render($form['title'][$key]),   // заголовок
      drupal_render($form['created'][$key]), // дата создания
    );
  }
 
  $output = theme('table', $form['header']['#value'], $rows); // выводим таблицу
  $output .= drupal_render($form);                            // выводим остальную часть формы
 
  return $output;
}
 
/**
 * Сабмит формы mymodule_form_table
 * Выводим в сообщении список выбранных нод
 */
function mymodule_form_table_submit($form, &$form_state) {
  $nids = array();
  foreach ($form_state['values']['nid'] as $nid) {
    if ($nid) {
      $nids[] = $nid;
    }
  }
 
  drupal_set_message('Выбраны ноды ' . implode(', ', $nids));
}

Код в работе Сабмит формы

А вот код который делает тоже самое, но с пагинацией и возможностью сортировки:

/**
 * Описание формы mymodule_form_table
 */
function mymodule_form_table() {
  // описание заголовков
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
       theme('table_select_header_cell'),
       array('data' => 'Заголовок', 'field' => 'title'),
       array('data' => 'Дата создания', 'field' => 'created', 'sort' => 'asc'),
    ),
  );
 
  // получаем список нод
  $nodes = pager_query("SELECT nid, title, created FROM {node}" . tablesort_sql($form['header']['#value']), 10);
 
  while ($node = db_fetch_object($nodes)) {
    $options[$node->nid] = '';
    // заголовок ноды в виде ссылки
    $form['title'][$node->nid] = array('#value' => l($node->title, 'node/' . $node->nid));
    // дата создания ноды
    $form['created'][$node->nid] = array('#value' => format_date($node->created));
  }
 
  $form['nid'] = array(
    '#type' => 'checkboxes',
    '#options' => isset($options) ? $options : array(),
  );
 
  $form['pager'] = array(
    '#value' => theme('pager', null, 10)
  );
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Удалить',
  );
 
  return $form;
}

Форма-таблица с пагинатором и сортировкой

Написанное актуально для Drupal 6
Похожие записи

Комментарии RSS

Интересно было бы скачать готовый компонент.
У меня не получилось с нуля собрать.

собирать ничего не нужно, в первом листинге полный и рабочий код модуля

Ошибка: А вот код который делает тоже самое, но с пагинацией и возможностью сортировки:

Сори - я не подумал слово "пагинация" - должно быть "навигация"

Спасибо, хорошее описание, написал модуль по нему (для работы с базой данных), и решил запихнуть все табличные формы в один модуль. Короче, как я понял темизация работала только для самой первой формы... В остальных не работала функция пейджера, хотя вроде как я все их включил в функцию темизации. Не уверен что правильно. И как сделать темизацию нескольких таблиц в одном модуле? Или надо писать под каждую таблицу свой модуль? Извиняюсь за подобные вопросы, совсем недавно начал писать что-либо под друпал.

И как сделать темизацию нескольких таблиц в одном модуле?

написать несколько темизирующих функций. или одну универсальну, которая не будет зависить от полей, например так — http://xandeadx.ru/blog/drupal/205

Они все написаны, сейчас сижу еще раз проверяю, две например вообще идентичные... Где ошибка не пойму. Кстати, эти функции находятся в разных .inc файла, может дело в этом? Дело в том, что у меня уже написано штук десять функций, и проверить все ли функции в них работают как-то неудосужился. И теперь когда уселся заполнять базу, и завел более 15 строк заметил, что пейджер работает в самой первой функции.
Вот пример переписаного хука theme:

function database_admin_theme()
{
    return array(
        'model_ref_form_table' => array(
           'arguments' => array('form' => null),
           'file' => 'model_ref.inc',
        ),
 
и т.д.
 
        'mark_ref_form_table' => array(
           'arguments' => array('form' => null),
           'file' => 'mark_ref.inc',
        ),
    );
}

Привильно ли указаны функции?

да, правильно

Было б хорошо увидеть пример для Drupal7

Было б хорошо увидеть пример для Drupal7

Это точно. Придется самому переписывать. Уж очень логично использовать такие формы в своих модулях.

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании