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

09.07.2010

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

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

Код, создающий по адресу 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
Похожие записи

Комментарии

Гость
04.11.2010, 16:09

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

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

Гость
24.12.2010, 06:44

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

Гость
24.12.2010, 06:48

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

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

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

написать несколько темизирующих функций. или одну универсальну, которая не будет зависить от полей, например так — 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',
        ),
    );
}

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

Виталий
09.08.2011, 18:44

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

Владимир
16.01.2012, 14:49

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

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

Гость
09.09.2020, 05:04

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

Добавить комментарий